mirror of
https://git.mirrors.martin98.com/https://github.com/google/draco
synced 2025-08-11 18:49:01 +08:00
Updated Draco to 1.1.0
The latest version of Draco brings a number of new compression enhancements for even smaller models: - Improved compression - Up to 40% better compression of normals - Up to 5% better compression for models with multiple attributes - Faster decode speeds - 30% faster decoding for models with multiple attributes for lower compression levels 4 and below - Note: Decreases compression by 10%. - Encoding of metadata to .obj (e.g. Draco can preserve material or sub-object names) - Security fixes
This commit is contained in:
parent
5da5579bc1
commit
dc28e6a2ea
@ -49,6 +49,7 @@ if (ENABLE_MESH_COMPRESSION)
|
|||||||
endif ()
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
|
||||||
# Turn on more compiler warnings.
|
# Turn on more compiler warnings.
|
||||||
if (ENABLE_EXTRA_WARNINGS)
|
if (ENABLE_EXTRA_WARNINGS)
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
@ -534,6 +535,7 @@ set(draco_test_sources
|
|||||||
"${draco_src_root}/core/symbol_coding_test.cc"
|
"${draco_src_root}/core/symbol_coding_test.cc"
|
||||||
"${draco_src_root}/core/vector_d_test.cc"
|
"${draco_src_root}/core/vector_d_test.cc"
|
||||||
"${draco_src_root}/io/obj_decoder_test.cc"
|
"${draco_src_root}/io/obj_decoder_test.cc"
|
||||||
|
"${draco_src_root}/io/obj_encoder_test.cc"
|
||||||
"${draco_src_root}/io/ply_decoder_test.cc"
|
"${draco_src_root}/io/ply_decoder_test.cc"
|
||||||
"${draco_src_root}/io/ply_reader_test.cc"
|
"${draco_src_root}/io/ply_reader_test.cc"
|
||||||
"${draco_src_root}/io/point_cloud_io_test.cc"
|
"${draco_src_root}/io/point_cloud_io_test.cc"
|
||||||
@ -565,12 +567,12 @@ if (EMSCRIPTEN)
|
|||||||
require_compiler_flag("--llvm-lto 1" YES)
|
require_compiler_flag("--llvm-lto 1" YES)
|
||||||
endif ()
|
endif ()
|
||||||
require_compiler_flag("-s NO_FILESYSTEM=1" YES)
|
require_compiler_flag("-s NO_FILESYSTEM=1" YES)
|
||||||
require_compiler_flag("-s ELIMINATE_DUPLICATE_FUNCTIONS=1" YES)
|
|
||||||
require_compiler_flag("-s EXPORTED_RUNTIME_METHODS=[]" YES)
|
require_compiler_flag("-s EXPORTED_RUNTIME_METHODS=[]" YES)
|
||||||
require_compiler_flag("-s PRECISE_F32=1" YES)
|
require_compiler_flag("-s PRECISE_F32=1" YES)
|
||||||
if (ENABLE_WASM)
|
if (ENABLE_WASM)
|
||||||
require_compiler_flag("-s WASM=1" YES)
|
require_compiler_flag("-s WASM=1" YES)
|
||||||
require_compiler_flag("-s BINARYEN_IMPRECISE=1" YES)
|
else ()
|
||||||
|
require_compiler_flag("-s ELIMINATE_DUPLICATE_FUNCTIONS=1" YES)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (CMAKE_BUILD_TYPE STREQUAL "")
|
if (CMAKE_BUILD_TYPE STREQUAL "")
|
||||||
@ -588,14 +590,17 @@ if (EMSCRIPTEN)
|
|||||||
execute_process(COMMAND ${PYTHON_EXECUTABLE}
|
execute_process(COMMAND ${PYTHON_EXECUTABLE}
|
||||||
$ENV{EMSCRIPTEN}/tools/webidl_binder.py
|
$ENV{EMSCRIPTEN}/tools/webidl_binder.py
|
||||||
${draco_js_dec_idl}
|
${draco_js_dec_idl}
|
||||||
${draco_build_dir}/glue_decoder
|
${draco_build_dir}/glue_decoder)
|
||||||
OUTPUT_FILE ${draco_build_dir}/glue_decoder.cpp)
|
|
||||||
|
|
||||||
execute_process(COMMAND ${PYTHON_EXECUTABLE}
|
execute_process(COMMAND ${PYTHON_EXECUTABLE}
|
||||||
$ENV{EMSCRIPTEN}/tools/webidl_binder.py
|
$ENV{EMSCRIPTEN}/tools/webidl_binder.py
|
||||||
${draco_js_enc_idl}
|
${draco_js_enc_idl}
|
||||||
${draco_build_dir}/glue_encoder
|
${draco_build_dir}/glue_encoder)
|
||||||
OUTPUT_FILE ${draco_build_dir}/glue_encoder.cpp)
|
|
||||||
|
if (NOT EXISTS "${draco_build_dir}/glue_decoder.cpp" OR
|
||||||
|
NOT EXISTS "${draco_build_dir}/glue_encoder.cpp")
|
||||||
|
message(FATAL_ERROR "Glue generation failed.")
|
||||||
|
endif ()
|
||||||
|
|
||||||
# Add a custom rule depending on the IDL to regenerate
|
# Add a custom rule depending on the IDL to regenerate
|
||||||
# ${draco_build_dir}/glue_decoder.cpp as needed.
|
# ${draco_build_dir}/glue_decoder.cpp as needed.
|
||||||
|
30
README.md
30
README.md
@ -5,23 +5,17 @@
|
|||||||
|
|
||||||
News
|
News
|
||||||
=======
|
=======
|
||||||
### Version 1.0.0 release
|
### Version 1.1.0 release
|
||||||
The latest version of Draco brings many new enhancements to improve the
|
The latest version of Draco brings a number of new compression enhancements for
|
||||||
development experience:
|
even smaller models:
|
||||||
* Stable API release
|
* Improved compression
|
||||||
* Support for npm Javascript package management
|
* Up to 40% better compression of normals
|
||||||
* Javascript based encoder
|
* Up to 5% better compression for models with multiple attributes
|
||||||
* Generalized metadata for meshes and point clouds
|
* Faster decode speeds
|
||||||
* Now supporting material properties included along with encoded file
|
* 30% faster decoding for models with multiple attributes for lower compression levels 4 and below
|
||||||
* Improved compression rates:
|
* Note: Decreases compression by 10%.
|
||||||
* 15% better compression on smaller models
|
* Encoding of metadata to .obj (e.g. Draco can preserve material or sub-object names)
|
||||||
* 40% better compression of normals
|
* Security fixes
|
||||||
* Performance improvements (~10% faster encoding, decoding)
|
|
||||||
* Reduced GPU memory usage:
|
|
||||||
* Option to store decoded quantized attributes
|
|
||||||
* Support for triangle strip connectivity on decoded meshes
|
|
||||||
* iOS 9 Javascript decoder
|
|
||||||
* Bitstream specification now available
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -54,7 +48,7 @@ _**Contents**_
|
|||||||
* [CMake Build Configuration](#cmake-build-config)
|
* [CMake Build Configuration](#cmake-build-config)
|
||||||
* [Debugging and Optimization](#debugging-and-optimization)
|
* [Debugging and Optimization](#debugging-and-optimization)
|
||||||
* [Googletest Integration](#googletest-integration)
|
* [Googletest Integration](#googletest-integration)
|
||||||
* [Javascript Decoder](#javascript-decoder)
|
* [Javascript Encoder/Decoder](#javascript-decoder)
|
||||||
* [Android Studio Project Integration](#android-studio-project-integration)
|
* [Android Studio Project Integration](#android-studio-project-integration)
|
||||||
* [Usage](#usage)
|
* [Usage](#usage)
|
||||||
* [Command Line Applications](#command-line-applications)
|
* [Command Line Applications](#command-line-applications)
|
||||||
|
File diff suppressed because one or more lines are too long
Binary file not shown.
30
javascript/draco_encoder.js
Normal file
30
javascript/draco_encoder.js
Normal file
File diff suppressed because one or more lines are too long
@ -1,124 +1,125 @@
|
|||||||
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(e,m,f){e!=Array.prototype&&e!=Object.prototype&&(e[m]=f.value)};$jscomp.getGlobal=function(e){return"undefined"!=typeof window&&window===e?e:"undefined"!=typeof global&&null!=global?global:e};$jscomp.global=$jscomp.getGlobal(this);
|
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(e,h,f){e!=Array.prototype&&e!=Object.prototype&&(e[h]=f.value)};$jscomp.getGlobal=function(e){return"undefined"!=typeof window&&window===e?e:"undefined"!=typeof global&&null!=global?global:e};$jscomp.global=$jscomp.getGlobal(this);
|
||||||
$jscomp.polyfill=function(e,m,f,z){if(m){f=$jscomp.global;e=e.split(".");for(z=0;z<e.length-1;z++){var h=e[z];h in f||(f[h]={});f=f[h]}e=e[e.length-1];z=f[e];m=m(z);m!=z&&null!=m&&$jscomp.defineProperty(f,e,{configurable:!0,writable:!0,value:m})}};$jscomp.polyfill("Math.imul",function(e){return e?e:function(e,f){e=Number(e);f=Number(f);var m=e&65535,h=f&65535;return m*h+((e>>>16&65535)*h+m*(f>>>16&65535)<<16>>>0)|0}},"es6","es3");
|
$jscomp.polyfill=function(e,h,f,z){if(h){f=$jscomp.global;e=e.split(".");for(z=0;z<e.length-1;z++){var k=e[z];k in f||(f[k]={});f=f[k]}e=e[e.length-1];z=f[e];h=h(z);h!=z&&null!=h&&$jscomp.defineProperty(f,e,{configurable:!0,writable:!0,value:h})}};$jscomp.polyfill("Math.imul",function(e){return e?e:function(e,f){e=Number(e);f=Number(f);var h=e&65535,k=f&65535;return h*k+((e>>>16&65535)*k+h*(f>>>16&65535)<<16>>>0)|0}},"es6","es3");
|
||||||
$jscomp.polyfill("Math.clz32",function(e){return e?e:function(e){e=Number(e)>>>0;if(0===e)return 32;var f=0;0===(e&4294901760)&&(e<<=16,f+=16);0===(e&4278190080)&&(e<<=8,f+=8);0===(e&4026531840)&&(e<<=4,f+=4);0===(e&3221225472)&&(e<<=2,f+=2);0===(e&2147483648)&&f++;return f}},"es6","es3");$jscomp.polyfill("Math.trunc",function(e){return e?e:function(e){e=Number(e);if(isNaN(e)||Infinity===e||-Infinity===e||0===e)return e;var f=Math.floor(Math.abs(e));return 0>e?-f:f}},"es6","es3");
|
$jscomp.polyfill("Math.clz32",function(e){return e?e:function(e){e=Number(e)>>>0;if(0===e)return 32;var f=0;0===(e&4294901760)&&(e<<=16,f+=16);0===(e&4278190080)&&(e<<=8,f+=8);0===(e&4026531840)&&(e<<=4,f+=4);0===(e&3221225472)&&(e<<=2,f+=2);0===(e&2147483648)&&f++;return f}},"es6","es3");$jscomp.polyfill("Math.trunc",function(e){return e?e:function(e){e=Number(e);if(isNaN(e)||Infinity===e||-Infinity===e||0===e)return e;var f=Math.floor(Math.abs(e));return 0>e?-f:f}},"es6","es3");
|
||||||
$jscomp.SYMBOL_PREFIX="jscomp_symbol_";$jscomp.initSymbol=function(){$jscomp.initSymbol=function(){};$jscomp.global.Symbol||($jscomp.global.Symbol=$jscomp.Symbol)};$jscomp.Symbol=function(){var e=0;return function(m){return $jscomp.SYMBOL_PREFIX+(m||"")+e++}}();
|
$jscomp.SYMBOL_PREFIX="jscomp_symbol_";$jscomp.initSymbol=function(){$jscomp.initSymbol=function(){};$jscomp.global.Symbol||($jscomp.global.Symbol=$jscomp.Symbol)};$jscomp.symbolCounter_=0;$jscomp.Symbol=function(e){return $jscomp.SYMBOL_PREFIX+(e||"")+$jscomp.symbolCounter_++};
|
||||||
$jscomp.initSymbolIterator=function(){$jscomp.initSymbol();var e=$jscomp.global.Symbol.iterator;e||(e=$jscomp.global.Symbol.iterator=$jscomp.global.Symbol("iterator"));"function"!=typeof Array.prototype[e]&&$jscomp.defineProperty(Array.prototype,e,{configurable:!0,writable:!0,value:function(){return $jscomp.arrayIterator(this)}});$jscomp.initSymbolIterator=function(){}};$jscomp.arrayIterator=function(e){var m=0;return $jscomp.iteratorPrototype(function(){return m<e.length?{done:!1,value:e[m++]}:{done:!0}})};
|
$jscomp.initSymbolIterator=function(){$jscomp.initSymbol();var e=$jscomp.global.Symbol.iterator;e||(e=$jscomp.global.Symbol.iterator=$jscomp.global.Symbol("iterator"));"function"!=typeof Array.prototype[e]&&$jscomp.defineProperty(Array.prototype,e,{configurable:!0,writable:!0,value:function(){return $jscomp.arrayIterator(this)}});$jscomp.initSymbolIterator=function(){}};$jscomp.arrayIterator=function(e){var h=0;return $jscomp.iteratorPrototype(function(){return h<e.length?{done:!1,value:e[h++]}:{done:!0}})};
|
||||||
$jscomp.iteratorPrototype=function(e){$jscomp.initSymbolIterator();e={next:e};e[$jscomp.global.Symbol.iterator]=function(){return this};return e};$jscomp.makeIterator=function(e){$jscomp.initSymbolIterator();var m=e[Symbol.iterator];return m?m.call(e):$jscomp.arrayIterator(e)};$jscomp.FORCE_POLYFILL_PROMISE=!1;
|
$jscomp.iteratorPrototype=function(e){$jscomp.initSymbolIterator();e={next:e};e[$jscomp.global.Symbol.iterator]=function(){return this};return e};$jscomp.makeIterator=function(e){$jscomp.initSymbolIterator();var h=e[Symbol.iterator];return h?h.call(e):$jscomp.arrayIterator(e)};$jscomp.FORCE_POLYFILL_PROMISE=!1;
|
||||||
$jscomp.polyfill("Promise",function(e){function m(){this.batch_=null}function f(e){return e instanceof h?e:new h(function(t,f){t(e)})}if(e&&!$jscomp.FORCE_POLYFILL_PROMISE)return e;m.prototype.asyncExecute=function(e){null==this.batch_&&(this.batch_=[],this.asyncExecuteBatch_());this.batch_.push(e);return this};m.prototype.asyncExecuteBatch_=function(){var e=this;this.asyncExecuteFunction(function(){e.executeBatch_()})};var z=$jscomp.global.setTimeout;m.prototype.asyncExecuteFunction=function(e){z(e,
|
$jscomp.polyfill("Promise",function(e){function h(){this.batch_=null}function f(e){return e instanceof k?e:new k(function(t,f){t(e)})}if(e&&!$jscomp.FORCE_POLYFILL_PROMISE)return e;h.prototype.asyncExecute=function(e){null==this.batch_&&(this.batch_=[],this.asyncExecuteBatch_());this.batch_.push(e);return this};h.prototype.asyncExecuteBatch_=function(){var e=this;this.asyncExecuteFunction(function(){e.executeBatch_()})};var z=$jscomp.global.setTimeout;h.prototype.asyncExecuteFunction=function(e){z(e,
|
||||||
0)};m.prototype.executeBatch_=function(){for(;this.batch_&&this.batch_.length;){var e=this.batch_;this.batch_=[];for(var f=0;f<e.length;++f){var h=e[f];delete e[f];try{h()}catch(qa){this.asyncThrow_(qa)}}}this.batch_=null};m.prototype.asyncThrow_=function(e){this.asyncExecuteFunction(function(){throw e;})};var h=function(e){this.state_=0;this.result_=void 0;this.onSettledCallbacks_=[];var f=this.createResolveAndReject_();try{e(f.resolve,f.reject)}catch(ia){f.reject(ia)}};h.prototype.createResolveAndReject_=
|
0)};h.prototype.executeBatch_=function(){for(;this.batch_&&this.batch_.length;){var e=this.batch_;this.batch_=[];for(var f=0;f<e.length;++f){var k=e[f];delete e[f];try{k()}catch(pa){this.asyncThrow_(pa)}}}this.batch_=null};h.prototype.asyncThrow_=function(e){this.asyncExecuteFunction(function(){throw e;})};var k=function(e){this.state_=0;this.result_=void 0;this.onSettledCallbacks_=[];var f=this.createResolveAndReject_();try{e(f.resolve,f.reject)}catch(ha){f.reject(ha)}};k.prototype.createResolveAndReject_=
|
||||||
function(){function e(e){return function(t){h||(h=!0,e.call(f,t))}}var f=this,h=!1;return{resolve:e(this.resolveTo_),reject:e(this.reject_)}};h.prototype.resolveTo_=function(e){if(e===this)this.reject_(new TypeError("A Promise cannot resolve to itself"));else if(e instanceof h)this.settleSameAsPromise_(e);else{a:switch(typeof e){case "object":var f=null!=e;break a;case "function":f=!0;break a;default:f=!1}f?this.resolveToNonPromiseObj_(e):this.fulfill_(e)}};h.prototype.resolveToNonPromiseObj_=function(e){var f=
|
function(){function e(e){return function(t){k||(k=!0,e.call(f,t))}}var f=this,k=!1;return{resolve:e(this.resolveTo_),reject:e(this.reject_)}};k.prototype.resolveTo_=function(e){if(e===this)this.reject_(new TypeError("A Promise cannot resolve to itself"));else if(e instanceof k)this.settleSameAsPromise_(e);else{a:switch(typeof e){case "object":var f=null!=e;break a;case "function":f=!0;break a;default:f=!1}f?this.resolveToNonPromiseObj_(e):this.fulfill_(e)}};k.prototype.resolveToNonPromiseObj_=function(e){var f=
|
||||||
void 0;try{f=e.then}catch(ia){this.reject_(ia);return}"function"==typeof f?this.settleSameAsThenable_(f,e):this.fulfill_(e)};h.prototype.reject_=function(e){this.settle_(2,e)};h.prototype.fulfill_=function(e){this.settle_(1,e)};h.prototype.settle_=function(e,f){if(0!=this.state_)throw Error("Cannot settle("+e+", "+f|"): Promise already settled in state"+this.state_);this.state_=e;this.result_=f;this.executeOnSettledCallbacks_()};h.prototype.executeOnSettledCallbacks_=function(){if(null!=this.onSettledCallbacks_){for(var e=
|
void 0;try{f=e.then}catch(ha){this.reject_(ha);return}"function"==typeof f?this.settleSameAsThenable_(f,e):this.fulfill_(e)};k.prototype.reject_=function(e){this.settle_(2,e)};k.prototype.fulfill_=function(e){this.settle_(1,e)};k.prototype.settle_=function(e,f){if(0!=this.state_)throw Error("Cannot settle("+e+", "+f|"): Promise already settled in state"+this.state_);this.state_=e;this.result_=f;this.executeOnSettledCallbacks_()};k.prototype.executeOnSettledCallbacks_=function(){if(null!=this.onSettledCallbacks_){for(var e=
|
||||||
this.onSettledCallbacks_,f=0;f<e.length;++f)e[f].call(),e[f]=null;this.onSettledCallbacks_=null}};var R=new m;h.prototype.settleSameAsPromise_=function(e){var f=this.createResolveAndReject_();e.callWhenSettled_(f.resolve,f.reject)};h.prototype.settleSameAsThenable_=function(e,f){var h=this.createResolveAndReject_();try{e.call(f,h.resolve,h.reject)}catch(qa){h.reject(qa)}};h.prototype.then=function(e,f){function m(e,f){return"function"==typeof e?function(f){try{t(e(f))}catch(ra){ja(ra)}}:f}var t,ja,
|
this.onSettledCallbacks_,f=0;f<e.length;++f)e[f].call(),e[f]=null;this.onSettledCallbacks_=null}};var R=new h;k.prototype.settleSameAsPromise_=function(e){var f=this.createResolveAndReject_();e.callWhenSettled_(f.resolve,f.reject)};k.prototype.settleSameAsThenable_=function(e,f){var k=this.createResolveAndReject_();try{e.call(f,k.resolve,k.reject)}catch(pa){k.reject(pa)}};k.prototype.then=function(e,f){function h(e,f){return"function"==typeof e?function(f){try{t(e(f))}catch(qa){ia(qa)}}:f}var t,ia,
|
||||||
z=new h(function(e,f){t=e;ja=f});this.callWhenSettled_(m(e,t),m(f,ja));return z};h.prototype.catch=function(e){return this.then(void 0,e)};h.prototype.callWhenSettled_=function(e,f){function h(){switch(m.state_){case 1:e(m.result_);break;case 2:f(m.result_);break;default:throw Error("Unexpected state: "+m.state_);}}var m=this;null==this.onSettledCallbacks_?R.asyncExecute(h):this.onSettledCallbacks_.push(function(){R.asyncExecute(h)})};h.resolve=f;h.reject=function(e){return new h(function(f,h){h(e)})};
|
z=new k(function(e,f){t=e;ia=f});this.callWhenSettled_(h(e,t),h(f,ia));return z};k.prototype.catch=function(e){return this.then(void 0,e)};k.prototype.callWhenSettled_=function(e,f){function k(){switch(h.state_){case 1:e(h.result_);break;case 2:f(h.result_);break;default:throw Error("Unexpected state: "+h.state_);}}var h=this;null==this.onSettledCallbacks_?R.asyncExecute(k):this.onSettledCallbacks_.push(function(){R.asyncExecute(k)})};k.resolve=f;k.reject=function(e){return new k(function(f,k){k(e)})};
|
||||||
h.race=function(e){return new h(function(h,m){for(var t=$jscomp.makeIterator(e),z=t.next();!z.done;z=t.next())f(z.value).callWhenSettled_(h,m)})};h.all=function(e){var m=$jscomp.makeIterator(e),t=m.next();return t.done?f([]):new h(function(e,h){function z(f){return function(h){ba[f]=h;R--;0==R&&e(ba)}}var ba=[],R=0;do ba.push(void 0),R++,f(t.value).callWhenSettled_(z(ba.length-1),h),t=m.next();while(!t.done)})};return h},"es6","es3");
|
k.race=function(e){return new k(function(k,h){for(var t=$jscomp.makeIterator(e),z=t.next();!z.done;z=t.next())f(z.value).callWhenSettled_(k,h)})};k.all=function(e){var h=$jscomp.makeIterator(e),t=h.next();return t.done?f([]):new k(function(e,k){function z(f){return function(k){ba[f]=k;R--;0==R&&e(ba)}}var ba=[],R=0;do ba.push(void 0),R++,f(t.value).callWhenSettled_(z(ba.length-1),k),t=h.next();while(!t.done)})};return k},"es6","es3");
|
||||||
var DracoDecoderModule=function(e){function m(a){eval.call(null,a)}function f(a,b){a||M("Assertion failed: "+b)}function z(d){var b=a["_"+d];if(!b)try{b=eval("_"+d)}catch(c){}f(b,"Cannot call unknown function "+d+" (perhaps LLVM optimizations or closure removed it?)");return b}function h(a,b,c){b=b||"i8";"*"===b.charAt(b.length-1)&&(b="i32");switch(b){case "i1":return N[a>>0];case "i8":return N[a>>0];case "i16":return sa[a>>1];case "i32":return u[a>>2];case "i64":return u[a>>2];case "float":return ya[a>>
|
var DracoDecoderModule=function(e){function h(a){eval.call(null,a)}function f(a,b){a||M("Assertion failed: "+b)}function z(d){var b=a["_"+d];if(!b)try{b=eval("_"+d)}catch(c){}f(b,"Cannot call unknown function "+d+" (perhaps LLVM optimizations or closure removed it?)");return b}function k(a,b,c){b=b||"i8";"*"===b.charAt(b.length-1)&&(b="i32");switch(b){case "i1":return N[a>>0];case "i8":return N[a>>0];case "i16":return ra[a>>1];case "i32":return u[a>>2];case "i64":return u[a>>2];case "float":return xa[a>>
|
||||||
2];case "double":return za[a>>3];default:M("invalid type for setValue: "+b)}return null}function R(a,b,c,g){if("number"===typeof a){var d=!0;var e=a}else d=!1,e=a.length;var S="string"===typeof b?b:null;c=4==c?g:["function"===typeof la?la:n.staticAlloc,n.stackAlloc,n.staticAlloc,n.dynamicAlloc][void 0===c?2:c](Math.max(e,S?1:b.length));if(d){g=c;f(0==(c&3));for(a=c+(e&-4);g<a;g+=4)u[g>>2]=0;for(a=c+e;g<a;)N[g++>>0]=0;return c}if("i8"===S)return a.subarray||a.slice?G.set(a,c):G.set(new Uint8Array(a),
|
2];case "double":return ya[a>>3];default:M("invalid type for setValue: "+b)}return null}function R(a,b,c,g){if("number"===typeof a){var d=!0;var e=a}else d=!1,e=a.length;var S="string"===typeof b?b:null;c=4==c?g:["function"===typeof ka?ka:n.staticAlloc,n.stackAlloc,n.staticAlloc,n.dynamicAlloc][void 0===c?2:c](Math.max(e,S?1:b.length));if(d){g=c;f(0==(c&3));for(a=c+(e&-4);g<a;g+=4)u[g>>2]=0;for(a=c+e;g<a;)N[g++>>0]=0;return c}if("i8"===S)return a.subarray||a.slice?G.set(a,c):G.set(new Uint8Array(a),
|
||||||
c),c;g=0;for(var h,m;g<e;){var k=a[g];"function"===typeof k&&(k=n.getFunctionIndex(k));d=S||b[g];if(0===d)g++;else{"i64"==d&&(d="i32");var l=c+g,ea=d;ea=ea||"i8";"*"===ea.charAt(ea.length-1)&&(ea="i32");switch(ea){case "i1":N[l>>0]=k;break;case "i8":N[l>>0]=k;break;case "i16":sa[l>>1]=k;break;case "i32":u[l>>2]=k;break;case "i64":tempI64=[k>>>0,(tempDouble=k,1<=+qb(tempDouble)?0<tempDouble?(rb(+sb(tempDouble/4294967296),4294967295)|0)>>>0:~~+tb((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)];
|
c),c;g=0;for(var k,m;g<e;){var h=a[g];"function"===typeof h&&(h=n.getFunctionIndex(h));d=S||b[g];if(0===d)g++;else{"i64"==d&&(d="i32");var l=c+g,p=d;p=p||"i8";"*"===p.charAt(p.length-1)&&(p="i32");switch(p){case "i1":N[l>>0]=h;break;case "i8":N[l>>0]=h;break;case "i16":ra[l>>1]=h;break;case "i32":u[l>>2]=h;break;case "i64":tempI64=[h>>>0,(tempDouble=h,1<=+pb(tempDouble)?0<tempDouble?(qb(+rb(tempDouble/4294967296),4294967295)|0)>>>0:~~+sb((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)];u[l>>2]=
|
||||||
u[l>>2]=tempI64[0];u[l+4>>2]=tempI64[1];break;case "float":ya[l>>2]=k;break;case "double":za[l>>3]=k;break;default:M("invalid type for setValue: "+ea)}m!==d&&(h=n.getNativeTypeSize(d),m=d);g+=h}}return c}function t(d,b){if(0===b||!d)return"";for(var c=0,g,e=0;;){g=G[d+e>>0];c|=g;if(0==g&&!b)break;e++;if(b&&e==b)break}b||(b=e);g="";if(128>c){for(;0<b;)c=String.fromCharCode.apply(String,G.subarray(d,d+Math.min(b,1024))),g=g?g+c:c,d+=1024,b-=1024;return g}return a.UTF8ToString(d)}function Ea(a,b,c,g){if(!(0<
|
tempI64[0];u[l+4>>2]=tempI64[1];break;case "float":xa[l>>2]=h;break;case "double":ya[l>>3]=h;break;default:M("invalid type for setValue: "+p)}m!==d&&(k=n.getNativeTypeSize(d),m=d);g+=k}}return c}function t(d,b){if(0===b||!d)return"";for(var c=0,g,e=0;;){g=G[d+e>>0];c|=g;if(0==g&&!b)break;e++;if(b&&e==b)break}b||(b=e);g="";if(128>c){for(;0<b;)c=String.fromCharCode.apply(String,G.subarray(d,d+Math.min(b,1024))),g=g?g+c:c,d+=1024,b-=1024;return g}return a.UTF8ToString(d)}function Da(a,b,c,g){if(!(0<
|
||||||
g))return 0;var d=c;g=c+g-1;for(var e=0;e<a.length;++e){var f=a.charCodeAt(e);55296<=f&&57343>=f&&(f=65536+((f&1023)<<10)|a.charCodeAt(++e)&1023);if(127>=f){if(c>=g)break;b[c++]=f}else{if(2047>=f){if(c+1>=g)break;b[c++]=192|f>>6}else{if(65535>=f){if(c+2>=g)break;b[c++]=224|f>>12}else{if(2097151>=f){if(c+3>=g)break;b[c++]=240|f>>18}else{if(67108863>=f){if(c+4>=g)break;b[c++]=248|f>>24}else{if(c+5>=g)break;b[c++]=252|f>>30;b[c++]=128|f>>24&63}b[c++]=128|f>>18&63}b[c++]=128|f>>12&63}b[c++]=128|f>>6&
|
g))return 0;var d=c;g=c+g-1;for(var e=0;e<a.length;++e){var f=a.charCodeAt(e);55296<=f&&57343>=f&&(f=65536+((f&1023)<<10)|a.charCodeAt(++e)&1023);if(127>=f){if(c>=g)break;b[c++]=f}else{if(2047>=f){if(c+1>=g)break;b[c++]=192|f>>6}else{if(65535>=f){if(c+2>=g)break;b[c++]=224|f>>12}else{if(2097151>=f){if(c+3>=g)break;b[c++]=240|f>>18}else{if(67108863>=f){if(c+4>=g)break;b[c++]=248|f>>24}else{if(c+5>=g)break;b[c++]=252|f>>30;b[c++]=128|f>>24&63}b[c++]=128|f>>18&63}b[c++]=128|f>>12&63}b[c++]=128|f>>6&
|
||||||
63}b[c++]=128|f&63}}b[c]=0;return c-d}function ia(a){for(var b=0,d=0;d<a.length;++d){var g=a.charCodeAt(d);55296<=g&&57343>=g&&(g=65536+((g&1023)<<10)|a.charCodeAt(++d)&1023);127>=g?++b:b=2047>=g?b+2:65535>=g?b+3:2097151>=g?b+4:67108863>=g?b+5:b+6}return b}function qa(d){return d.replace(/__Z[\w\d_]+/g,function(b){a:{var d=a.___cxa_demangle||a.__cxa_demangle;if(d)try{var g=b.substr(1),e=ia(g)+1;var f=la(e);Ea(g,G,f,e);var k=la(4);var l=d(f,0,0,k);if(0===h(k,"i32")&&l){var m=t(l);break a}}catch(xd){}finally{f&&
|
63}b[c++]=128|f&63}}b[c]=0;return c-d}function ha(a){for(var b=0,d=0;d<a.length;++d){var g=a.charCodeAt(d);55296<=g&&57343>=g&&(g=65536+((g&1023)<<10)|a.charCodeAt(++d)&1023);127>=g?++b:b=2047>=g?b+2:65535>=g?b+3:2097151>=g?b+4:67108863>=g?b+5:b+6}return b}function pa(d){return d.replace(/__Z[\w\d_]+/g,function(b){a:{var d=a.___cxa_demangle||a.__cxa_demangle;if(d)try{var g=b.substr(1),e=ha(g)+1;var f=ka(e);Da(g,G,f,e);var h=ka(4);var l=d(f,0,0,h);if(0===k(h,"i32")&&l){var m=t(l);break a}}catch(xd){}finally{f&&
|
||||||
Ia(f),k&&Ia(k),l&&Ia(l)}else n.warnOnce("warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling");m=b}return b===m?b:b+" ["+m+"]"})}function ja(){a:{var d=Error();if(!d.stack){try{throw Error(0);}catch(b){d=b}if(!d.stack){d="(no stack trace available)";break a}}d=d.stack.toString()}a.extraStackTrace&&(d+="\n"+a.extraStackTrace());return qa(d)}function Fa(a,b){0<a%b&&(a+=b-a%b);return a}function ba(){a.HEAP8=N=new Int8Array(H);a.HEAP16=sa=new Int16Array(H);a.HEAP32=u=new Int32Array(H);
|
Ha(f),h&&Ha(h),l&&Ha(l)}else n.warnOnce("warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling");m=b}return b===m?b:b+" ["+m+"]"})}function ia(){a:{var d=Error();if(!d.stack){try{throw Error(0);}catch(b){d=b}if(!d.stack){d="(no stack trace available)";break a}}d=d.stack.toString()}a.extraStackTrace&&(d+="\n"+a.extraStackTrace());return pa(d)}function Ea(a,b){0<a%b&&(a+=b-a%b);return a}function ba(){a.HEAP8=N=new Int8Array(H);a.HEAP16=ra=new Int16Array(H);a.HEAP32=u=new Int32Array(H);
|
||||||
a.HEAPU8=G=new Uint8Array(H);a.HEAPU16=Wa=new Uint16Array(H);a.HEAPU32=Xa=new Uint32Array(H);a.HEAPF32=ya=new Float32Array(H);a.HEAPF64=za=new Float64Array(H)}function Va(){var d=a.usingWasm?Ja:Ya,b=2147483648-d;if(u[X>>2]>b)return!1;var c=x;for(x=Math.max(x,ub);x<u[X>>2];)x=536870912>=x?Fa(2*x,d):Math.min(Fa((3*x+2147483648)/4,d),b);d=a.reallocBuffer(x);if(!d||d.byteLength!=x)return x=c,!1;a.buffer=H=d;ba();return!0}function ka(d){for(;0<d.length;){var b=d.shift();if("function"==typeof b)b();else{var c=
|
a.HEAPU8=G=new Uint8Array(H);a.HEAPU16=Va=new Uint16Array(H);a.HEAPU32=Wa=new Uint32Array(H);a.HEAPF32=xa=new Float32Array(H);a.HEAPF64=ya=new Float64Array(H)}function Ua(){var d=a.usingWasm?Ia:Xa,b=2147483648-d;if(u[Y>>2]>b)return!1;var c=x;for(x=Math.max(x,tb);x<u[Y>>2];)x=536870912>=x?Ea(2*x,d):Math.min(Ea((3*x+2147483648)/4,d),b);d=a.reallocBuffer(x);if(!d||d.byteLength!=x)return x=c,!1;a.buffer=H=d;ba();return!0}function ja(d){for(;0<d.length;){var b=d.shift();if("function"==typeof b)b();else{var c=
|
||||||
b.func;"number"===typeof c?void 0===b.arg?a.dynCall_v(c):a.dynCall_vi(c,b.arg):c(void 0===b.arg?null:b.arg)}}}function ra(a,b,c){c=0<c?c:ia(a)+1;c=Array(c);a=Ea(a,c,0,c.length);b&&(c.length=a);return c}function Za(d){fa++;a.monitorRunDependencies&&a.monitorRunDependencies(fa)}function $a(d){fa--;a.monitorRunDependencies&&a.monitorRunDependencies(fa);0==fa&&(null!==Ka&&(clearInterval(Ka),Ka=null),ta&&(d=ta,ta=null,d()))}function ma(){return!!ma.uncaught_exception}function ua(){var d=C.last;if(!d)return(n.setTempRet0(0),
|
b.func;"number"===typeof c?void 0===b.arg?a.dynCall_v(c):a.dynCall_vi(c,b.arg):c(void 0===b.arg?null:b.arg)}}}function qa(a,b,c){c=0<c?c:ha(a)+1;c=Array(c);a=Da(a,c,0,c.length);b&&(c.length=a);return c}function Ya(d){ea++;a.monitorRunDependencies&&a.monitorRunDependencies(ea)}function Za(d){ea--;a.monitorRunDependencies&&a.monitorRunDependencies(ea);0==ea&&(null!==Ja&&(clearInterval(Ja),Ja=null),sa&&(d=sa,sa=null,d()))}function la(){return!!la.uncaught_exception}function ta(){var d=C.last;if(!d)return(n.setTempRet0(0),
|
||||||
0)|0;var b=C.infos[d],c=b.type;if(!c)return(n.setTempRet0(0),d)|0;var g=Array.prototype.slice.call(arguments);a.___cxa_is_pointer_type(c);ua.buffer||(ua.buffer=la(4));u[ua.buffer>>2]=d;d=ua.buffer;for(var e=0;e<g.length;e++)if(g[e]&&a.___cxa_can_catch(g[e],c,d))return d=u[d>>2],b.adjusted=d,(n.setTempRet0(g[e]),d)|0;d=u[d>>2];return(n.setTempRet0(c),d)|0}function va(d,b){va.seen||(va.seen={});d in va.seen||(a.dynCall_v(b),va.seen[d]=1)}function ca(d,b){r.varargs=b;try{var c=r.get(),g=r.get(),e=r.get();
|
0)|0;var b=C.infos[d],c=b.type;if(!c)return(n.setTempRet0(0),d)|0;var g=Array.prototype.slice.call(arguments);a.___cxa_is_pointer_type(c);ta.buffer||(ta.buffer=ka(4));u[ta.buffer>>2]=d;d=ta.buffer;for(var e=0;e<g.length;e++)if(g[e]&&a.___cxa_can_catch(g[e],c,d))return d=u[d>>2],b.adjusted=d,(n.setTempRet0(g[e]),d)|0;d=u[d>>2];return(n.setTempRet0(c),d)|0}function ua(d,b){ua.seen||(ua.seen={});d in ua.seen||(a.dynCall_v(b),ua.seen[d]=1)}function ca(d,b){r.varargs=b;try{var c=r.get(),g=r.get(),e=r.get();
|
||||||
d=0;ca.buffer||(ca.buffers=[null,[],[]],ca.printChar=function(b,d){var c=ca.buffers[b];f(c);if(0===d||10===d){b=1===b?a.print:a.printErr;a:{for(var e=d=0;c[e];)++e;if(16<e-d&&c.subarray&&ab)d=ab.decode(c.subarray(d,e));else for(e="";;){var g=c[d++];if(!g){d=e;break a}if(g&128){var h=c[d++]&63;if(192==(g&224))e+=String.fromCharCode((g&31)<<6|h);else{var k=c[d++]&63;if(224==(g&240))g=(g&15)<<12|h<<6|k;else{var l=c[d++]&63;if(240==(g&248))g=(g&7)<<18|h<<12|k<<6|l;else{var A=c[d++]&63;if(248==(g&252))g=
|
d=0;ca.buffer||(ca.buffers=[null,[],[]],ca.printChar=function(b,d){var c=ca.buffers[b];f(c);if(0===d||10===d){b=1===b?a.print:a.printErr;a:{for(var g=d=0;c[g];)++g;if(16<g-d&&c.subarray&&$a)d=$a.decode(c.subarray(d,g));else for(g="";;){var e=c[d++];if(!e){d=g;break a}if(e&128){var h=c[d++]&63;if(192==(e&224))g+=String.fromCharCode((e&31)<<6|h);else{var k=c[d++]&63;if(224==(e&240))e=(e&15)<<12|h<<6|k;else{var l=c[d++]&63;if(240==(e&248))e=(e&7)<<18|h<<12|k<<6|l;else{var A=c[d++]&63;if(248==(e&252))e=
|
||||||
(g&3)<<24|h<<18|k<<12|l<<6|A;else{var m=c[d++]&63;g=(g&1)<<30|h<<24|k<<18|l<<12|A<<6|m}}}65536>g?e+=String.fromCharCode(g):(g-=65536,e+=String.fromCharCode(55296|g>>10,56320|g&1023))}}else e+=String.fromCharCode(g)}}b(d);c.length=0}else c.push(d)});for(b=0;b<e;b++){for(var k=u[g+8*b>>2],h=u[g+(8*b+4)>>2],l=0;l<h;l++)ca.printChar(c,G[k+l]);d+=h}return d}catch(Ha){return"undefined"!==typeof FS&&Ha instanceof FS.ErrnoError||M(Ha),-Ha.errno}}function na(a){this.name="ExitStatus";this.message="Program terminated with exit("+
|
(e&3)<<24|h<<18|k<<12|l<<6|A;else{var m=c[d++]&63;e=(e&1)<<30|h<<24|k<<18|l<<12|A<<6|m}}}65536>e?g+=String.fromCharCode(e):(e-=65536,g+=String.fromCharCode(55296|e>>10,56320|e&1023))}}else g+=String.fromCharCode(e)}}b(d);c.length=0}else c.push(d)});for(b=0;b<e;b++){for(var h=u[g+8*b>>2],k=u[g+(8*b+4)>>2],l=0;l<k;l++)ca.printChar(c,G[h+l]);d+=k}return d}catch(Ga){return"undefined"!==typeof FS&&Ga instanceof FS.ErrnoError||M(Ga),-Ga.errno}}function ma(a){this.name="ExitStatus";this.message="Program terminated with exit("+
|
||||||
a+")";this.status=a}function La(d){function b(){if(!a.calledRun&&(a.calledRun=!0,!oa)){Aa||(Aa=!0,ka(Ma));ka(bb);if(a.onRuntimeInitialized)a.onRuntimeInitialized();a._main&&cb&&a.callMain(d);if(a.postRun)for("function"==typeof a.postRun&&(a.postRun=[a.postRun]);a.postRun.length;)db.unshift(a.postRun.shift());ka(db)}}d=d||a.arguments;null===eb&&(eb=Date.now());if(!(0<fa)){if(a.preRun)for("function"==typeof a.preRun&&(a.preRun=[a.preRun]);a.preRun.length;)fb.unshift(a.preRun.shift());ka(fb);0<fa||a.calledRun||
|
a+")";this.status=a}function Ka(d){function b(){if(!a.calledRun&&(a.calledRun=!0,!na)){za||(za=!0,ja(La));ja(ab);if(a.onRuntimeInitialized)a.onRuntimeInitialized();a._main&&bb&&a.callMain(d);if(a.postRun)for("function"==typeof a.postRun&&(a.postRun=[a.postRun]);a.postRun.length;)cb.unshift(a.postRun.shift());ja(cb)}}d=d||a.arguments;null===db&&(db=Date.now());if(!(0<ea)){if(a.preRun)for("function"==typeof a.preRun&&(a.preRun=[a.preRun]);a.preRun.length;)eb.unshift(a.preRun.shift());ja(eb);0<ea||a.calledRun||
|
||||||
(a.setStatus?(a.setStatus("Running..."),setTimeout(function(){setTimeout(function(){a.setStatus("")},1);b()},1)):b())}}function gb(d,b){if(!b||!a.noExitRuntime){if(!a.noExitRuntime&&(oa=!0,T=vb,ka(hb),a.onExit))a.onExit(d);pa&&process.exit(d);a.quit(d,new na(d))}}function M(d){if(a.onAbort)a.onAbort(d);void 0!==d?(a.print(d),a.printErr(d),d=JSON.stringify(d)):d="";oa=!0;var b="abort("+d+") at "+ja()+"\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.";ib&&
|
(a.setStatus?(a.setStatus("Running..."),setTimeout(function(){setTimeout(function(){a.setStatus("")},1);b()},1)):b())}}function fb(d,b){if(!b||!a.noExitRuntime){if(!a.noExitRuntime&&(na=!0,T=ub,ja(gb),a.onExit))a.onExit(d);oa&&process.exit(d);a.quit(d,new ma(d))}}function M(d){if(a.onAbort)a.onAbort(d);void 0!==d?(a.print(d),a.printErr(d),d=JSON.stringify(d)):d="";na=!0;var b="abort("+d+") at "+ia()+"\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.";hb&&
|
||||||
ib.forEach(function(a){b=a(b,d)});throw b;}function v(){}function E(a){return(a||v).__cache__}function Y(a,b){var d=E(b),g=d[a];if(g)return g;g=Object.create((b||v).prototype);g.ptr=a;return d[a]=g}function Z(a){if("string"===typeof a){a=ra(a);var b=k.alloc(a,N);k.copy(a,N,b);return b}return a}function D(){throw"cannot construct a Status, no constructor in IDL";}function I(){this.ptr=wb();E(I)[this.ptr]=this}function J(){this.ptr=xb();E(J)[this.ptr]=this}function p(){this.ptr=yb();E(p)[this.ptr]=
|
hb.forEach(function(a){b=a(b,d)});throw b;}function v(){}function E(a){return(a||v).__cache__}function V(a,b){var d=E(b),e=d[a];if(e)return e;e=Object.create((b||v).prototype);e.ptr=a;return d[a]=e}function Z(a){if("string"===typeof a){a=qa(a);var b=l.alloc(a,N);l.copy(a,N,b);return b}return a}function D(){throw"cannot construct a Status, no constructor in IDL";}function I(){this.ptr=vb();E(I)[this.ptr]=this}function J(){this.ptr=wb();E(J)[this.ptr]=this}function p(){this.ptr=xb();E(p)[this.ptr]=
|
||||||
this}function O(){this.ptr=zb();E(O)[this.ptr]=this}function B(){this.ptr=Ab();E(B)[this.ptr]=this}function q(){this.ptr=Bb();E(q)[this.ptr]=this}function K(){this.ptr=Cb();E(K)[this.ptr]=this}function V(){this.ptr=Db();E(V)[this.ptr]=this}function P(){this.ptr=Eb();E(P)[this.ptr]=this}function l(){this.ptr=Fb();E(l)[this.ptr]=this}function F(){this.ptr=Gb();E(F)[this.ptr]=this}function aa(){throw"cannot construct a VoidPtr, no constructor in IDL";}function L(){this.ptr=Hb();E(L)[this.ptr]=this}function Q(){this.ptr=
|
this}function O(){this.ptr=yb();E(O)[this.ptr]=this}function B(){this.ptr=zb();E(B)[this.ptr]=this}function q(){this.ptr=Ab();E(q)[this.ptr]=this}function K(){this.ptr=Bb();E(K)[this.ptr]=this}function W(){this.ptr=Cb();E(W)[this.ptr]=this}function P(){this.ptr=Db();E(P)[this.ptr]=this}function m(){this.ptr=Eb();E(m)[this.ptr]=this}function F(){this.ptr=Fb();E(F)[this.ptr]=this}function aa(){throw"cannot construct a VoidPtr, no constructor in IDL";}function L(){this.ptr=Gb();E(L)[this.ptr]=this}function Q(){this.ptr=
|
||||||
Ib();E(Q)[this.ptr]=this}var a=e=e||{},jb=!1,kb=!1;a.onRuntimeInitialized=function(){jb=!0;if(kb&&"function"===typeof a.onModuleLoaded)a.onModuleLoaded(a)};a.onModuleParsed=function(){kb=!0;if(jb&&"function"===typeof a.onModuleLoaded)a.onModuleLoaded(a)};a.isVersionSupported=function(a){if("string"!==typeof a)return!1;a=a.split(".");return 2>a.length||3<a.length?!1:1==a[0]&&0==a[1]?!0:0!=a[0]||10<a[1]?!1:!0};a||(a=("undefined"!==typeof e?e:null)||{});var wa={},da;for(da in a)a.hasOwnProperty(da)&&
|
Hb();E(Q)[this.ptr]=this}var a=e=e||{},ib=!1,jb=!1;a.onRuntimeInitialized=function(){ib=!0;if(jb&&"function"===typeof a.onModuleLoaded)a.onModuleLoaded(a)};a.onModuleParsed=function(){jb=!0;if(ib&&"function"===typeof a.onModuleLoaded)a.onModuleLoaded(a)};a.isVersionSupported=function(a){if("string"!==typeof a)return!1;a=a.split(".");return 2>a.length||3<a.length?!1:1==a[0]&&0==a[1]?!0:0!=a[0]||10<a[1]?!1:!0};a||(a=("undefined"!==typeof e?e:null)||{});var va={},da;for(da in a)a.hasOwnProperty(da)&&
|
||||||
(wa[da]=a[da]);var xa=!1,ha=!1,pa=!1,Ba=!1;if(a.ENVIRONMENT)if("WEB"===a.ENVIRONMENT)xa=!0;else if("WORKER"===a.ENVIRONMENT)ha=!0;else if("NODE"===a.ENVIRONMENT)pa=!0;else if("SHELL"===a.ENVIRONMENT)Ba=!0;else throw Error("The provided Module['ENVIRONMENT'] value is not valid. It must be one of: WEB|WORKER|NODE|SHELL.");else xa="object"===typeof window,ha="function"===typeof importScripts,pa="object"===typeof process&&"function"===typeof require&&!xa&&!ha,Ba=!xa&&!pa&&!ha;if(pa){a.print||(a.print=
|
(va[da]=a[da]);var wa=!1,fa=!1,oa=!1,Aa=!1;if(a.ENVIRONMENT)if("WEB"===a.ENVIRONMENT)wa=!0;else if("WORKER"===a.ENVIRONMENT)fa=!0;else if("NODE"===a.ENVIRONMENT)oa=!0;else if("SHELL"===a.ENVIRONMENT)Aa=!0;else throw Error("The provided Module['ENVIRONMENT'] value is not valid. It must be one of: WEB|WORKER|NODE|SHELL.");else wa="object"===typeof window,fa="function"===typeof importScripts,oa="object"===typeof process&&"function"===typeof require&&!wa&&!fa,Aa=!wa&&!oa&&!fa;if(oa){a.print||(a.print=
|
||||||
console.log);a.printErr||(a.printErr=console.warn);var Na,Oa;a.read=function(a,b){Na||(Na=require("fs"));Oa||(Oa=require("path"));a=Oa.normalize(a);a=Na.readFileSync(a);return b?a:a.toString()};a.readBinary=function(d){d=a.read(d,!0);d.buffer||(d=new Uint8Array(d));f(d.buffer);return d};a.load=function(a){m(read(a))};a.thisProgram||(a.thisProgram=1<process.argv.length?process.argv[1].replace(/\\/g,"/"):"unknown-program");a.arguments=process.argv.slice(2);"undefined"!==typeof module&&(module.exports=
|
console.log);a.printErr||(a.printErr=console.warn);var Ma,Na;a.read=function(a,b){Ma||(Ma=require("fs"));Na||(Na=require("path"));a=Na.normalize(a);a=Ma.readFileSync(a);return b?a:a.toString()};a.readBinary=function(d){d=a.read(d,!0);d.buffer||(d=new Uint8Array(d));f(d.buffer);return d};a.load=function(a){h(read(a))};a.thisProgram||(a.thisProgram=1<process.argv.length?process.argv[1].replace(/\\/g,"/"):"unknown-program");a.arguments=process.argv.slice(2);"undefined"!==typeof module&&(module.exports=
|
||||||
a);process.on("uncaughtException",function(a){if(!(a instanceof na))throw a;});a.inspect=function(){return"[Emscripten Module object]"}}else if(Ba)a.print||(a.print=print),"undefined"!=typeof printErr&&(a.printErr=printErr),a.read="undefined"!=typeof read?read:function(){throw"no read() available";},a.readBinary=function(a){if("function"===typeof readbuffer)return new Uint8Array(readbuffer(a));a=read(a,"binary");f("object"===typeof a);return a},"undefined"!=typeof scriptArgs?a.arguments=scriptArgs:
|
a);process.on("uncaughtException",function(a){if(!(a instanceof ma))throw a;});a.inspect=function(){return"[Emscripten Module object]"}}else if(Aa)a.print||(a.print=print),"undefined"!=typeof printErr&&(a.printErr=printErr),a.read="undefined"!=typeof read?read:function(){throw"no read() available";},a.readBinary=function(a){if("function"===typeof readbuffer)return new Uint8Array(readbuffer(a));a=read(a,"binary");f("object"===typeof a);return a},"undefined"!=typeof scriptArgs?a.arguments=scriptArgs:
|
||||||
"undefined"!=typeof arguments&&(a.arguments=arguments),"function"===typeof quit&&(a.quit=function(a,b){quit(a)});else if(xa||ha)a.read=function(a){var b=new XMLHttpRequest;b.open("GET",a,!1);b.send(null);return b.responseText},ha&&(a.readBinary=function(a){var b=new XMLHttpRequest;b.open("GET",a,!1);b.responseType="arraybuffer";b.send(null);return new Uint8Array(b.response)}),a.readAsync=function(a,b,c){var d=new XMLHttpRequest;d.open("GET",a,!0);d.responseType="arraybuffer";d.onload=function(){200==
|
"undefined"!=typeof arguments&&(a.arguments=arguments),"function"===typeof quit&&(a.quit=function(a,b){quit(a)});else if(wa||fa)a.read=function(a){var b=new XMLHttpRequest;b.open("GET",a,!1);b.send(null);return b.responseText},fa&&(a.readBinary=function(a){var b=new XMLHttpRequest;b.open("GET",a,!1);b.responseType="arraybuffer";b.send(null);return new Uint8Array(b.response)}),a.readAsync=function(a,b,c){var d=new XMLHttpRequest;d.open("GET",a,!0);d.responseType="arraybuffer";d.onload=function(){200==
|
||||||
d.status||0==d.status&&d.response?b(d.response):c()};d.onerror=c;d.send(null)},"undefined"!=typeof arguments&&(a.arguments=arguments),"undefined"!==typeof console?(a.print||(a.print=function(a){console.log(a)}),a.printErr||(a.printErr=function(a){console.warn(a)})):a.print||(a.print=function(a){}),ha&&(a.load=importScripts),"undefined"===typeof a.setWindowTitle&&(a.setWindowTitle=function(a){document.title=a});else throw"Unknown runtime environment. Where are we?";!a.load&&a.read&&(a.load=function(d){m(a.read(d))});
|
d.status||0==d.status&&d.response?b(d.response):c()};d.onerror=c;d.send(null)},"undefined"!=typeof arguments&&(a.arguments=arguments),"undefined"!==typeof console?(a.print||(a.print=function(a){console.log(a)}),a.printErr||(a.printErr=function(a){console.warn(a)})):a.print||(a.print=function(a){}),fa&&(a.load=importScripts),"undefined"===typeof a.setWindowTitle&&(a.setWindowTitle=function(a){document.title=a});else throw"Unknown runtime environment. Where are we?";!a.load&&a.read&&(a.load=function(d){h(a.read(d))});
|
||||||
a.print||(a.print=function(){});a.printErr||(a.printErr=a.print);a.arguments||(a.arguments=[]);a.thisProgram||(a.thisProgram="./this.program");a.quit||(a.quit=function(a,b){throw b;});a.print=a.print;a.printErr=a.printErr;a.preRun=[];a.postRun=[];for(da in wa)wa.hasOwnProperty(da)&&(a[da]=wa[da]);wa=void 0;var n={setTempRet0:function(a){return tempRet0=a},getTempRet0:function(){return tempRet0},stackSave:function(){return T},stackRestore:function(a){T=a},getNativeTypeSize:function(a){switch(a){case "i1":case "i8":return 1;
|
a.print||(a.print=function(){});a.printErr||(a.printErr=a.print);a.arguments||(a.arguments=[]);a.thisProgram||(a.thisProgram="./this.program");a.quit||(a.quit=function(a,b){throw b;});a.print=a.print;a.printErr=a.printErr;a.preRun=[];a.postRun=[];for(da in va)va.hasOwnProperty(da)&&(a[da]=va[da]);va=void 0;var n={setTempRet0:function(a){return tempRet0=a},getTempRet0:function(){return tempRet0},stackSave:function(){return T},stackRestore:function(a){T=a},getNativeTypeSize:function(a){switch(a){case "i1":case "i8":return 1;
|
||||||
case "i16":return 2;case "i32":return 4;case "i64":return 8;case "float":return 4;case "double":return 8;default:return"*"===a[a.length-1]?n.QUANTUM_SIZE:"i"===a[0]?(a=parseInt(a.substr(1)),f(0===a%8),a/8):0}},getNativeFieldSize:function(a){return Math.max(n.getNativeTypeSize(a),n.QUANTUM_SIZE)},STACK_ALIGN:16,prepVararg:function(a,b){"double"===b||"i64"===b?a&7&&(f(4===(a&7)),a+=4):f(0===(a&3));return a},getAlignSize:function(a,b,c){return c||"i64"!=a&&"double"!=a?a?Math.min(b||(a?n.getNativeFieldSize(a):
|
case "i16":return 2;case "i32":return 4;case "i64":return 8;case "float":return 4;case "double":return 8;default:return"*"===a[a.length-1]?n.QUANTUM_SIZE:"i"===a[0]?(a=parseInt(a.substr(1)),f(0===a%8),a/8):0}},getNativeFieldSize:function(a){return Math.max(n.getNativeTypeSize(a),n.QUANTUM_SIZE)},STACK_ALIGN:16,prepVararg:function(a,b){"double"===b||"i64"===b?a&7&&(f(4===(a&7)),a+=4):f(0===(a&3));return a},getAlignSize:function(a,b,c){return c||"i64"!=a&&"double"!=a?a?Math.min(b||(a?n.getNativeFieldSize(a):
|
||||||
0),n.QUANTUM_SIZE):Math.min(b,8):8},dynCall:function(d,b,c){return c&&c.length?a["dynCall_"+d].apply(null,[b].concat(c)):a["dynCall_"+d].call(null,b)},functionPointers:[],addFunction:function(a){for(var b=0;b<n.functionPointers.length;b++)if(!n.functionPointers[b])return n.functionPointers[b]=a,2*(1+b);throw"Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS.";},removeFunction:function(a){n.functionPointers[(a-2)/2]=null},warnOnce:function(d){n.warnOnce.shown||
|
0),n.QUANTUM_SIZE):Math.min(b,8):8},dynCall:function(d,b,c){return c&&c.length?a["dynCall_"+d].apply(null,[b].concat(c)):a["dynCall_"+d].call(null,b)},functionPointers:[],addFunction:function(a){for(var b=0;b<n.functionPointers.length;b++)if(!n.functionPointers[b])return n.functionPointers[b]=a,2*(1+b);throw"Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS.";},removeFunction:function(a){n.functionPointers[(a-2)/2]=null},warnOnce:function(d){n.warnOnce.shown||
|
||||||
(n.warnOnce.shown={});n.warnOnce.shown[d]||(n.warnOnce.shown[d]=1,a.printErr(d))},funcWrappers:{},getFuncWrapper:function(a,b){f(b);n.funcWrappers[b]||(n.funcWrappers[b]={});var d=n.funcWrappers[b];d[a]||(d[a]=1===b.length?function(){return n.dynCall(b,a)}:2===b.length?function(d){return n.dynCall(b,a,[d])}:function(){return n.dynCall(b,a,Array.prototype.slice.call(arguments))});return d[a]},getCompilerSetting:function(a){throw"You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work";
|
(n.warnOnce.shown={});n.warnOnce.shown[d]||(n.warnOnce.shown[d]=1,a.printErr(d))},funcWrappers:{},getFuncWrapper:function(a,b){f(b);n.funcWrappers[b]||(n.funcWrappers[b]={});var d=n.funcWrappers[b];d[a]||(d[a]=1===b.length?function(){return n.dynCall(b,a)}:2===b.length?function(d){return n.dynCall(b,a,[d])}:function(){return n.dynCall(b,a,Array.prototype.slice.call(arguments))});return d[a]},getCompilerSetting:function(a){throw"You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work";
|
||||||
},stackAlloc:function(a){var b=T;T=T+a|0;T=T+15&-16;return b},staticAlloc:function(a){var b=W;W=W+a|0;W=W+15&-16;return b},dynamicAlloc:function(a){var b=u[X>>2];a=(b+a+15|0)&-16;u[X>>2]=a;return a>=x&&!Va()?(u[X>>2]=b,0):b},alignMemory:function(a,b){return Math.ceil(a/(b?b:16))*(b?b:16)},makeBigInt:function(a,b,c){return c?+(a>>>0)+4294967296*+(b>>>0):+(a>>>0)+4294967296*+(b|0)},GLOBAL_BASE:1024,QUANTUM_SIZE:4,__dummy__:0},oa=0;(function(){function a(a){a=a.toString().match(e).slice(1);return{arguments:a[0],
|
},stackAlloc:function(a){var b=T;T=T+a|0;T=T+15&-16;return b},staticAlloc:function(a){var b=X;X=X+a|0;X=X+15&-16;return b},dynamicAlloc:function(a){var b=u[Y>>2];a=(b+a+15|0)&-16;u[Y>>2]=a;return a>=x&&!Ua()?(u[Y>>2]=b,0):b},alignMemory:function(a,b){return Math.ceil(a/(b?b:16))*(b?b:16)},makeBigInt:function(a,b,c){return c?+(a>>>0)+4294967296*+(b>>>0):+(a>>>0)+4294967296*+(b|0)},GLOBAL_BASE:1024,QUANTUM_SIZE:4,__dummy__:0},na=0;(function(){function a(a){a=a.toString().match(e).slice(1);return{arguments:a[0],
|
||||||
body:a[1],returnValue:a[2]}}function b(){if(!f){f={};for(var b in c)c.hasOwnProperty(b)&&(f[b]=a(c[b]))}}var c={stackSave:function(){n.stackSave()},stackRestore:function(){n.stackRestore()},arrayToC:function(a){var b=n.stackAlloc(a.length);N.set(a,b);return b},stringToC:function(a){var b=0;if(null!==a&&void 0!==a&&0!==a){var d=(a.length<<2)+1;b=n.stackAlloc(d);Ea(a,G,b,d)}return b}},e=/^function\s*[a-zA-Z$_0-9]*\s*\(([^)]*)\)\s*{\s*([^*]*?)[\s;]*(?:return\s*(.*?)[;\s]*)?}$/,f=null;cwrap=function(d,
|
body:a[1],returnValue:a[2]}}function b(){if(!f){f={};for(var b in c)c.hasOwnProperty(b)&&(f[b]=a(c[b]))}}var c={stackSave:function(){n.stackSave()},stackRestore:function(){n.stackRestore()},arrayToC:function(a){var b=n.stackAlloc(a.length);N.set(a,b);return b},stringToC:function(a){var b=0;if(null!==a&&void 0!==a&&0!==a){var d=(a.length<<2)+1;b=n.stackAlloc(d);Da(a,G,b,d)}return b}},e=/^function\s*[a-zA-Z$_0-9]*\s*\(([^)]*)\)\s*{\s*([^*]*?)[\s;]*(?:return\s*(.*?)[;\s]*)?}$/,f=null;cwrap=function(d,
|
||||||
c,e){e=e||[];var g=z(d);d=e.every(function(a){return"number"===a});var h="string"!==c;if(h&&d)return g;var k=e.map(function(a,b){return"$"+b});c="(function("+k.join(",")+") {";var l=e.length;if(!d){b();c+="var stack = "+f.stackSave.body+";";for(var m=0;m<l;m++){var A=k[m],n=e[m];"number"!==n&&(n=f[n+"ToC"],c+="var "+n.arguments+" = "+A+";",c+=n.body+";",c+=A+"=("+n.returnValue+");")}}e=a(function(){return g}).returnValue;c+="var ret = "+e+"("+k.join(",")+");";h||(e=a(function(){return t}).returnValue,
|
c,e){e=e||[];var g=z(d);d=e.every(function(a){return"number"===a});var h="string"!==c;if(h&&d)return g;var k=e.map(function(a,b){return"$"+b});c="(function("+k.join(",")+") {";var l=e.length;if(!d){b();c+="var stack = "+f.stackSave.body+";";for(var m=0;m<l;m++){var A=k[m],n=e[m];"number"!==n&&(n=f[n+"ToC"],c+="var "+n.arguments+" = "+A+";",c+=n.body+";",c+=A+"=("+n.returnValue+");")}}e=a(function(){return g}).returnValue;c+="var ret = "+e+"("+k.join(",")+");";h||(e=a(function(){return t}).returnValue,
|
||||||
c+="ret = "+e+"(ret);");d||(b(),c+=f.stackRestore.body.replace("()","(stack)")+";");return eval(c+"return ret})")}})();var ab="undefined"!==typeof TextDecoder?new TextDecoder("utf8"):void 0;"undefined"!==typeof TextDecoder&&new TextDecoder("utf-16le");var Ja=65536,Ya=16777216,ub=16777216,N,G,sa,Wa,u,Xa,ya,za,W,Pa,T,Ca,Qa,X;var Ra=W=Pa=T=Ca=Qa=X=0;a.reallocBuffer||(a.reallocBuffer=function(a){try{if(ArrayBuffer.transfer)var b=ArrayBuffer.transfer(H,a);else{var d=N;b=new ArrayBuffer(a);(new Int8Array(b)).set(d)}}catch(g){return!1}return Jb(b)?
|
c+="ret = "+e+"(ret);");d||(b(),c+=f.stackRestore.body.replace("()","(stack)")+";");return eval(c+"return ret})")}})();var $a="undefined"!==typeof TextDecoder?new TextDecoder("utf8"):void 0;"undefined"!==typeof TextDecoder&&new TextDecoder("utf-16le");var Ia=65536,Xa=16777216,tb=16777216,N,G,ra,Va,u,Wa,xa,ya,X,Oa,T,Ba,Pa,Y;var Qa=X=Oa=T=Ba=Pa=Y=0;a.reallocBuffer||(a.reallocBuffer=function(a){try{if(ArrayBuffer.transfer)var b=ArrayBuffer.transfer(H,a);else{var d=N;b=new ArrayBuffer(a);(new Int8Array(b)).set(d)}}catch(g){return!1}return Ib(b)?
|
||||||
b:!1});try{var Sa=Function.prototype.call.bind(Object.getOwnPropertyDescriptor(ArrayBuffer.prototype,"byteLength").get);Sa(new ArrayBuffer(4))}catch(d){Sa=function(a){return a.byteLength}}var Ta=a.TOTAL_STACK||5242880,x=a.TOTAL_MEMORY||16777216;x<Ta&&a.printErr("TOTAL_MEMORY should be larger than TOTAL_STACK, was "+x+"! (TOTAL_STACK="+Ta+")");if(a.buffer)var H=a.buffer;else"object"===typeof WebAssembly&&"function"===typeof WebAssembly.Memory?(a.wasmMemory=new WebAssembly.Memory({initial:x/Ja}),H=
|
b:!1});try{var Ra=Function.prototype.call.bind(Object.getOwnPropertyDescriptor(ArrayBuffer.prototype,"byteLength").get);Ra(new ArrayBuffer(4))}catch(d){Ra=function(a){return a.byteLength}}var Sa=a.TOTAL_STACK||5242880,x=a.TOTAL_MEMORY||16777216;x<Sa&&a.printErr("TOTAL_MEMORY should be larger than TOTAL_STACK, was "+x+"! (TOTAL_STACK="+Sa+")");if(a.buffer)var H=a.buffer;else"object"===typeof WebAssembly&&"function"===typeof WebAssembly.Memory?(a.wasmMemory=new WebAssembly.Memory({initial:x/Ia}),H=
|
||||||
a.wasmMemory.buffer):H=new ArrayBuffer(x);ba();u[0]=1668509029;sa[1]=25459;if(115!==G[2]||99!==G[3])throw"Runtime error: expected the system to be little-endian!";a.HEAP=void 0;a.buffer=H;a.HEAP8=N;a.HEAP16=sa;a.HEAP32=u;a.HEAPU8=G;a.HEAPU16=Wa;a.HEAPU32=Xa;a.HEAPF32=ya;a.HEAPF64=za;var fb=[],Ma=[],bb=[],hb=[],db=[],Aa=!1;Math.imul&&-5===Math.imul(4294967295,5)||(Math.imul=function(a,b){var d=a&65535,e=b&65535;return d*e+((a>>>16)*e+d*(b>>>16)<<16)|0});Math.imul=Math.imul;if(!Math.fround){var lb=
|
a.wasmMemory.buffer):H=new ArrayBuffer(x);ba();u[0]=1668509029;ra[1]=25459;if(115!==G[2]||99!==G[3])throw"Runtime error: expected the system to be little-endian!";a.HEAP=void 0;a.buffer=H;a.HEAP8=N;a.HEAP16=ra;a.HEAP32=u;a.HEAPU8=G;a.HEAPU16=Va;a.HEAPU32=Wa;a.HEAPF32=xa;a.HEAPF64=ya;var eb=[],La=[],ab=[],gb=[],cb=[],za=!1;Math.imul&&-5===Math.imul(4294967295,5)||(Math.imul=function(a,b){var d=a&65535,e=b&65535;return d*e+((a>>>16)*e+d*(b>>>16)<<16)|0});Math.imul=Math.imul;if(!Math.fround){var kb=
|
||||||
new Float32Array(1);Math.fround=function(a){lb[0]=a;return lb[0]}}Math.fround=Math.fround;Math.clz32||(Math.clz32=function(a){a>>>=0;for(var b=0;32>b;b++)if(a&1<<31-b)return b;return 32});Math.clz32=Math.clz32;Math.trunc||(Math.trunc=function(a){return 0>a?Math.ceil(a):Math.floor(a)});Math.trunc=Math.trunc;var qb=Math.abs,tb=Math.ceil,sb=Math.floor,rb=Math.min,fa=0,Ka=null,ta=null;a.preloadedImages={};a.preloadedAudios={};var U=null;(function(d){function b(a,b){var d=t;if(0>a.indexOf("."))d=(d||{})[a];
|
new Float32Array(1);Math.fround=function(a){kb[0]=a;return kb[0]}}Math.fround=Math.fround;Math.clz32||(Math.clz32=function(a){a>>>=0;for(var b=0;32>b;b++)if(a&1<<31-b)return b;return 32});Math.clz32=Math.clz32;Math.trunc||(Math.trunc=function(a){return 0>a?Math.ceil(a):Math.floor(a)});Math.trunc=Math.trunc;var pb=Math.abs,sb=Math.ceil,rb=Math.floor,qb=Math.min,ea=0,Ja=null,sa=null;a.preloadedImages={};a.preloadedAudios={};var U=null;(function(d){function b(a,b){var d=t;if(0>a.indexOf("."))d=(d||{})[a];
|
||||||
else{var c=a.split(".");d=(d||{})[c[0]];d=(d||{})[c[1]]}b&&(d=(d||{})[b]);void 0===d&&M("bad lookupImport to ("+a+")."+b);return d}function c(b){var c=d.buffer;b.byteLength<c.byteLength&&d.printErr("the new buffer in mergeMemory is smaller than the previous one. in native wasm, we should grow memory here");c=new Int8Array(c);var e=new Int8Array(b);U||c.set(e.subarray(d.STATIC_BASE,d.STATIC_BASE+d.STATIC_BUMP),d.STATIC_BASE);e.set(c);a.buffer=H=b;ba()}function e(){try{if(d.wasmBinary){var a=d.wasmBinary;
|
else{var c=a.split(".");d=(d||{})[c[0]];d=(d||{})[c[1]]}b&&(d=(d||{})[b]);void 0===d&&M("bad lookupImport to ("+a+")."+b);return d}function c(b){var c=d.buffer;b.byteLength<c.byteLength&&d.printErr("the new buffer in mergeMemory is smaller than the previous one. in native wasm, we should grow memory here");c=new Int8Array(c);var e=new Int8Array(b);U||c.set(e.subarray(d.STATIC_BASE,d.STATIC_BASE+d.STATIC_BUMP),d.STATIC_BASE);e.set(c);a.buffer=H=b;ba()}function e(){try{if(d.wasmBinary){var a=d.wasmBinary;
|
||||||
a=new Uint8Array(a)}else if(d.readBinary)a=d.readBinary(p);else throw"on the web, we need the wasm binary to be preloaded and set on Module['wasmBinary']. emcc.py will do that for you when generating HTML (but not JS)";return a}catch(Kb){M(Kb)}}function h(){return d.wasmBinary||"function"!==typeof fetch?new Promise(function(a,b){a(e())}):fetch(p,{credentials:"same-origin"}).then(function(a){if(!a.ok)throw"failed to load wasm binary file at '"+p+"'";return a.arrayBuffer()})}function k(a,b,c){if("function"!==
|
a=new Uint8Array(a)}else if(d.readBinary)a=d.readBinary(p);else throw"on the web, we need the wasm binary to be preloaded and set on Module['wasmBinary']. emcc.py will do that for you when generating HTML (but not JS)";return a}catch(Jb){M(Jb)}}function h(){return d.wasmBinary||"function"!==typeof fetch?new Promise(function(a,b){a(e())}):fetch(p,{credentials:"same-origin"}).then(function(a){if(!a.ok)throw"failed to load wasm binary file at '"+p+"'";return a.arrayBuffer()})}function k(a,b,c){if("function"!==
|
||||||
typeof d.asm||d.asm===x)d.asmPreload?d.asm=d.asmPreload:eval(d.read(v));return"function"!==typeof d.asm?(d.printErr("asm evalling did not set the module properly"),!1):d.asm(a,b,c)}function l(a,b,e){function g(a){u=a.exports;u.memory&&c(u.memory);d.asm=u;d.usingWasm=!0;$a("wasm-instantiate")}if("object"!==typeof WebAssembly)return d.printErr("no native wasm support detected"),!1;if(!(d.wasmMemory instanceof WebAssembly.Memory))return d.printErr("no native wasm Memory in use"),!1;b.memory=d.wasmMemory;
|
typeof d.asm||d.asm===x)d.asmPreload?d.asm=d.asmPreload:eval(d.read(v));return"function"!==typeof d.asm?(d.printErr("asm evalling did not set the module properly"),!1):d.asm(a,b,c)}function l(a,b,e){function g(a){u=a.exports;u.memory&&c(u.memory);d.asm=u;d.usingWasm=!0;Za("wasm-instantiate")}if("object"!==typeof WebAssembly)return d.printErr("no native wasm support detected"),!1;if(!(d.wasmMemory instanceof WebAssembly.Memory))return d.printErr("no native wasm Memory in use"),!1;b.memory=d.wasmMemory;
|
||||||
t.global={NaN:NaN,Infinity:Infinity};t["global.Math"]=a.Math;t.env=b;Za("wasm-instantiate");if(d.instantiateWasm)try{return d.instantiateWasm(t,g)}catch(Lb){return d.printErr("Module.instantiateWasm callback failed with error: "+Lb),!1}h().then(function(a){return WebAssembly.instantiate(a,t)}).then(function(a){g(a.instance)}).catch(function(a){d.printErr("failed to asynchronously prepare wasm: "+a);M(a)});return{}}var m=d.wasmJSMethod||"native-wasm";d.wasmJSMethod=m;var n=d.wasmTextFile||"draco_decoder.wast",
|
t.global={NaN:NaN,Infinity:Infinity};t["global.Math"]=a.Math;t.env=b;Ya("wasm-instantiate");if(d.instantiateWasm)try{return d.instantiateWasm(t,g)}catch(Kb){return d.printErr("Module.instantiateWasm callback failed with error: "+Kb),!1}h().then(function(a){return WebAssembly.instantiate(a,t)}).then(function(a){g(a.instance)}).catch(function(a){d.printErr("failed to asynchronously prepare wasm: "+a);M(a)});return{}}var m=d.wasmJSMethod||"native-wasm";d.wasmJSMethod=m;var n=d.wasmTextFile||"draco_decoder.wast",
|
||||||
p=d.wasmBinaryFile||"draco_decoder.wasm",v=d.asmjsCodeFile||"draco_decoder.temp.asm.js";"function"===typeof d.locateFile&&(n=d.locateFile(n),p=d.locateFile(p),v=d.locateFile(v));var t={global:null,env:null,asm2wasm:{"f64-rem":function(a,b){return a%b},"f64-to-int":function(a){return a|0},"i32s-div":function(a,b){return(a|0)/(b|0)|0},"i32u-div":function(a,b){return(a>>>0)/(b>>>0)>>>0},"i32s-rem":function(a,b){return(a|0)%(b|0)|0},"i32u-rem":function(a,b){return(a>>>0)%(b>>>0)>>>0},"debugger":function(){debugger}},
|
p=d.wasmBinaryFile||"draco_decoder.wasm",v=d.asmjsCodeFile||"draco_decoder.temp.asm.js";"function"===typeof d.locateFile&&(n=d.locateFile(n),p=d.locateFile(p),v=d.locateFile(v));var t={global:null,env:null,asm2wasm:{"f64-rem":function(a,b){return a%b},"f64-to-int":function(a){return a|0},"i32s-div":function(a,b){return(a|0)/(b|0)|0},"i32u-div":function(a,b){return(a>>>0)/(b>>>0)>>>0},"i32s-rem":function(a,b){return(a|0)%(b|0)|0},"i32u-rem":function(a,b){return(a>>>0)%(b>>>0)>>>0},"debugger":function(){debugger}},
|
||||||
parent:d},u=null;d.asmPreload=d.asm;var q=d.reallocBuffer,r=function(a){a=Fa(a,d.usingWasm?Ja:Ya);var b=d.buffer,c=b.byteLength;if(d.usingWasm)try{return-1!==d.wasmMemory.grow((a-c)/65536)?d.buffer=d.wasmMemory.buffer:null}catch(yd){return null}else return u.__growWasmMemory((a-c)/65536),d.buffer!==b?d.buffer:null};d.reallocBuffer=function(a){return"asmjs"===z?q(a):r(a)};var z="";d.asm=function(a,g,h){if(!g.table){var A=d.wasmTableSize;void 0===A&&(A=1024);var p=d.wasmMaxTableSize;g.table="object"===
|
parent:d},u=null;d.asmPreload=d.asm;var q=d.reallocBuffer,r=function(a){a=Ea(a,d.usingWasm?Ia:Xa);var b=d.buffer,c=b.byteLength;if(d.usingWasm)try{return-1!==d.wasmMemory.grow((a-c)/65536)?d.buffer=d.wasmMemory.buffer:null}catch(yd){return null}else return u.__growWasmMemory((a-c)/65536),d.buffer!==b?d.buffer:null};d.reallocBuffer=function(a){return"asmjs"===z?q(a):r(a)};var z="";d.asm=function(a,g,h){if(!g.table){var A=d.wasmTableSize;void 0===A&&(A=1024);var p=d.wasmMaxTableSize;g.table="object"===
|
||||||
typeof WebAssembly&&"function"===typeof WebAssembly.Table?void 0!==p?new WebAssembly.Table({initial:A,maximum:p,element:"anyfunc"}):new WebAssembly.Table({initial:A,element:"anyfunc"}):Array(A);d.wasmTable=g.table}g.memoryBase||(g.memoryBase=d.STATIC_BASE);g.tableBase||(g.tableBase=0);var q;A=m.split(",");for(p=0;p<A.length;p++){var w=A[p];z=w;if("native-wasm"===w){if(q=l(a,g,h))break}else if("asmjs"===w){if(q=k(a,g,h))break}else if("interpret-asm2wasm"===w||"interpret-s-expr"===w||"interpret-binary"===
|
typeof WebAssembly&&"function"===typeof WebAssembly.Table?void 0!==p?new WebAssembly.Table({initial:A,maximum:p,element:"anyfunc"}):new WebAssembly.Table({initial:A,element:"anyfunc"}):Array(A);d.wasmTable=g.table}g.memoryBase||(g.memoryBase=d.STATIC_BASE);g.tableBase||(g.tableBase=0);var q;A=m.split(",");for(p=0;p<A.length;p++){var w=A[p];z=w;if("native-wasm"===w){if(q=l(a,g,h))break}else if("asmjs"===w){if(q=k(a,g,h))break}else if("interpret-asm2wasm"===w||"interpret-s-expr"===w||"interpret-binary"===
|
||||||
w){q=a;var r=g;var x=h,y=w;if("function"!==typeof WasmJS)d.printErr("WasmJS not detected - polyfill not bundled?"),w=!1;else{w=WasmJS({});w.outside=d;w.info=t;w.lookupImport=b;f(x===d.buffer);t.global=q;t.env=r;f(x===d.buffer);r.memory=x;f(r.memory instanceof ArrayBuffer);w.providedTotalMemory=d.buffer.byteLength;q="interpret-binary"===y?e():d.read("interpret-asm2wasm"==y?v:n);if("interpret-asm2wasm"==y)r=w._malloc(q.length+1),w.writeAsciiToMemory(q,r),w._load_asm2wasm(r);else if("interpret-s-expr"===
|
w){q=a;var r=g;var x=h,y=w;if("function"!==typeof WasmJS)d.printErr("WasmJS not detected - polyfill not bundled?"),w=!1;else{w=WasmJS({});w.outside=d;w.info=t;w.lookupImport=b;f(x===d.buffer);t.global=q;t.env=r;f(x===d.buffer);r.memory=x;f(r.memory instanceof ArrayBuffer);w.providedTotalMemory=d.buffer.byteLength;q="interpret-binary"===y?e():d.read("interpret-asm2wasm"==y?v:n);if("interpret-asm2wasm"==y)r=w._malloc(q.length+1),w.writeAsciiToMemory(q,r),w._load_asm2wasm(r);else if("interpret-s-expr"===
|
||||||
y)r=w._malloc(q.length+1),w.writeAsciiToMemory(q,r),w._load_s_expr2wasm(r);else if("interpret-binary"===y)r=w._malloc(q.length),w.HEAPU8.set(q,r),w._load_binary2wasm(r,q.length);else throw"what? "+y;w._free(r);w._instantiate(r);d.newBuffer&&(c(d.newBuffer),d.newBuffer=null);w=u=w.asmExports}if(q=w)break}else M("bad method: "+w)}if(!q)throw"no binaryen method succeeded. consider enabling more options, like interpreting, if you want that: https://github.com/kripken/emscripten/wiki/WebAssembly#binaryen-methods";
|
y)r=w._malloc(q.length+1),w.writeAsciiToMemory(q,r),w._load_s_expr2wasm(r);else if("interpret-binary"===y)r=w._malloc(q.length),w.HEAPU8.set(q,r),w._load_binary2wasm(r,q.length);else throw"what? "+y;w._free(r);w._instantiate(r);d.newBuffer&&(c(d.newBuffer),d.newBuffer=null);w=u=w.asmExports}if(q=w)break}else M("bad method: "+w)}if(!q)throw"no binaryen method succeeded. consider enabling more options, like interpreting, if you want that: https://github.com/kripken/emscripten/wiki/WebAssembly#binaryen-methods";
|
||||||
return q};var x=d.asm})(a);Ra=n.GLOBAL_BASE;W=Ra+28960;Ma.push();U=0<=a.wasmJSMethod.indexOf("asmjs")||0<=a.wasmJSMethod.indexOf("interpret-asm2wasm")?"draco_decoder.js.mem":null;a.STATIC_BASE=Ra;a.STATIC_BUMP=28960;var Mb=W;W+=16;var C={last:0,caught:[],infos:{},deAdjust:function(a){if(!a||C.infos[a])return a;for(var b in C.infos)if(C.infos[b].adjusted===a)return b;return a},addRef:function(a){a&&C.infos[a].refcount++},decRef:function(d){if(d){var b=C.infos[d];f(0<b.refcount);b.refcount--;0!==b.refcount||
|
return q};var x=d.asm})(a);Qa=n.GLOBAL_BASE;X=Qa+28928;La.push();U=0<=a.wasmJSMethod.indexOf("asmjs")||0<=a.wasmJSMethod.indexOf("interpret-asm2wasm")?"draco_decoder.js.mem":null;a.STATIC_BASE=Qa;a.STATIC_BUMP=28928;var Lb=X;X+=16;var C={last:0,caught:[],infos:{},deAdjust:function(a){if(!a||C.infos[a])return a;for(var b in C.infos)if(C.infos[b].adjusted===a)return b;return a},addRef:function(a){a&&C.infos[a].refcount++},decRef:function(d){if(d){var b=C.infos[d];f(0<b.refcount);b.refcount--;0!==b.refcount||
|
||||||
b.rethrown||(b.destructor&&a.dynCall_vi(b.destructor,d),delete C.infos[d],___cxa_free_exception(d))}},clearRef:function(a){a&&(C.infos[a].refcount=0)}};a._memset=Nb;a._memcpy=Ob;var r={varargs:0,get:function(a){r.varargs+=4;return u[r.varargs-4>>2]},getStr:function(){return t(r.get())},get64:function(){var a=r.get(),b=r.get();0<=a?f(0===b):f(-1===b);return a},getZero:function(){f(0===r.get())}},Da={};a._sbrk=Pb;a._memmove=Qb;var Ua=1;a._llvm_bswap_i32=Rb;hb.push(function(){var d=a._fflush;d&&d(0);
|
b.rethrown||(b.destructor&&a.dynCall_vi(b.destructor,d),delete C.infos[d],___cxa_free_exception(d))}},clearRef:function(a){a&&(C.infos[a].refcount=0)}};a._memset=Mb;a._memcpy=Nb;var r={varargs:0,get:function(a){r.varargs+=4;return u[r.varargs-4>>2]},getStr:function(){return t(r.get())},get64:function(){var a=r.get(),b=r.get();0<=a?f(0===b):f(-1===b);return a},getZero:function(){f(0===r.get())}},Ca={};a._sbrk=Ob;a._memmove=Pb;var Ta=1;a._llvm_bswap_i32=Qb;gb.push(function(){var d=a._fflush;d&&d(0);
|
||||||
if(d=ca.printChar){var b=ca.buffers;b[1].length&&d(1,10);b[2].length&&d(2,10)}});X=R(1,"i32",2);Pa=T=n.alignMemory(W);Ca=Pa+Ta;Qa=n.alignMemory(Ca);u[X>>2]=Qa;a.wasmTableSize=780;a.wasmMaxTableSize=780;a.asmGlobalArg={Math:Math,Int8Array:Int8Array,Int16Array:Int16Array,Int32Array:Int32Array,Uint8Array:Uint8Array,Uint16Array:Uint16Array,Uint32Array:Uint32Array,Float32Array:Float32Array,Float64Array:Float64Array,NaN:NaN,Infinity:Infinity,byteLength:Sa};a.asmLibraryArg={abort:M,assert:f,enlargeMemory:Va,
|
if(d=ca.printChar){var b=ca.buffers;b[1].length&&d(1,10);b[2].length&&d(2,10)}});Y=R(1,"i32",2);Oa=T=n.alignMemory(X);Ba=Oa+Sa;Pa=n.alignMemory(Ba);u[Y>>2]=Pa;a.wasmTableSize=780;a.wasmMaxTableSize=780;a.asmGlobalArg={Math:Math,Int8Array:Int8Array,Int16Array:Int16Array,Int32Array:Int32Array,Uint8Array:Uint8Array,Uint16Array:Uint16Array,Uint32Array:Uint32Array,Float32Array:Float32Array,Float64Array:Float64Array,NaN:NaN,Infinity:Infinity,byteLength:Ra};a.asmLibraryArg={abort:M,assert:f,enlargeMemory:Ua,
|
||||||
getTotalMemory:function(){return x},abortOnCannotGrowMemory:function(){M("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+x+", (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ")},invoke_iiii:function(d,b,c,e){try{return a.dynCall_iiii(d,b,c,e)}catch(A){if("number"!==typeof A&&"longjmp"!==A)throw A;
|
getTotalMemory:function(){return x},abortOnCannotGrowMemory:function(){M("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+x+", (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ")},invoke_iiii:function(d,b,c,e){try{return a.dynCall_iiii(d,b,c,e)}catch(A){if("number"!==typeof A&&"longjmp"!==A)throw A;
|
||||||
a.setThrew(1,0)}},invoke_viiiii:function(d,b,c,e,f,h){try{a.dynCall_viiiii(d,b,c,e,f,h)}catch(S){if("number"!==typeof S&&"longjmp"!==S)throw S;a.setThrew(1,0)}},invoke_vi:function(d,b){try{a.dynCall_vi(d,b)}catch(c){if("number"!==typeof c&&"longjmp"!==c)throw c;a.setThrew(1,0)}},invoke_vii:function(d,b,c){try{a.dynCall_vii(d,b,c)}catch(g){if("number"!==typeof g&&"longjmp"!==g)throw g;a.setThrew(1,0)}},invoke_iiiiiii:function(d,b,c,e,f,h,k){try{return a.dynCall_iiiiiii(d,b,c,e,f,h,k)}catch(y){if("number"!==
|
a.setThrew(1,0)}},invoke_viiiii:function(d,b,c,e,f,h){try{a.dynCall_viiiii(d,b,c,e,f,h)}catch(S){if("number"!==typeof S&&"longjmp"!==S)throw S;a.setThrew(1,0)}},invoke_vi:function(d,b){try{a.dynCall_vi(d,b)}catch(c){if("number"!==typeof c&&"longjmp"!==c)throw c;a.setThrew(1,0)}},invoke_vii:function(d,b,c){try{a.dynCall_vii(d,b,c)}catch(g){if("number"!==typeof g&&"longjmp"!==g)throw g;a.setThrew(1,0)}},invoke_iiiiiii:function(d,b,c,e,f,h,k){try{return a.dynCall_iiiiiii(d,b,c,e,f,h,k)}catch(y){if("number"!==
|
||||||
typeof y&&"longjmp"!==y)throw y;a.setThrew(1,0)}},invoke_ii:function(d,b){try{return a.dynCall_ii(d,b)}catch(c){if("number"!==typeof c&&"longjmp"!==c)throw c;a.setThrew(1,0)}},invoke_viii:function(d,b,c,e){try{a.dynCall_viii(d,b,c,e)}catch(A){if("number"!==typeof A&&"longjmp"!==A)throw A;a.setThrew(1,0)}},invoke_v:function(d){try{a.dynCall_v(d)}catch(b){if("number"!==typeof b&&"longjmp"!==b)throw b;a.setThrew(1,0)}},invoke_viiiiii:function(d,b,c,e,f,h,k){try{a.dynCall_viiiiii(d,b,c,e,f,h,k)}catch(y){if("number"!==
|
typeof y&&"longjmp"!==y)throw y;a.setThrew(1,0)}},invoke_ii:function(d,b){try{return a.dynCall_ii(d,b)}catch(c){if("number"!==typeof c&&"longjmp"!==c)throw c;a.setThrew(1,0)}},invoke_viii:function(d,b,c,e){try{a.dynCall_viii(d,b,c,e)}catch(A){if("number"!==typeof A&&"longjmp"!==A)throw A;a.setThrew(1,0)}},invoke_v:function(d){try{a.dynCall_v(d)}catch(b){if("number"!==typeof b&&"longjmp"!==b)throw b;a.setThrew(1,0)}},invoke_viiiiii:function(d,b,c,e,f,h,k){try{a.dynCall_viiiiii(d,b,c,e,f,h,k)}catch(y){if("number"!==
|
||||||
typeof y&&"longjmp"!==y)throw y;a.setThrew(1,0)}},invoke_iii:function(d,b,c){try{return a.dynCall_iii(d,b,c)}catch(g){if("number"!==typeof g&&"longjmp"!==g)throw g;a.setThrew(1,0)}},invoke_viiii:function(d,b,c,e,f){try{a.dynCall_viiii(d,b,c,e,f)}catch(Ga){if("number"!==typeof Ga&&"longjmp"!==Ga)throw Ga;a.setThrew(1,0)}},_pthread_getspecific:function(a){return Da[a]||0},___syscall54:function(a,b){r.varargs=b;return 0},_pthread_setspecific:function(a,b){if(!(a in Da))return 22;Da[a]=b;return 0},___cxa_throw:function(a,
|
typeof y&&"longjmp"!==y)throw y;a.setThrew(1,0)}},invoke_iii:function(d,b,c){try{return a.dynCall_iii(d,b,c)}catch(g){if("number"!==typeof g&&"longjmp"!==g)throw g;a.setThrew(1,0)}},invoke_viiii:function(d,b,c,e,f){try{a.dynCall_viiii(d,b,c,e,f)}catch(Fa){if("number"!==typeof Fa&&"longjmp"!==Fa)throw Fa;a.setThrew(1,0)}},_pthread_getspecific:function(a){return Ca[a]||0},___syscall54:function(a,b){r.varargs=b;return 0},_pthread_setspecific:function(a,b){if(!(a in Ca))return 22;Ca[a]=b;return 0},___cxa_throw:function(a,
|
||||||
b,c){C.infos[a]={ptr:a,adjusted:a,type:b,destructor:c,refcount:0,caught:!1,rethrown:!1};C.last=a;"uncaught_exception"in ma?ma.uncaught_exception++:ma.uncaught_exception=1;throw a+" - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch.";},___gxx_personality_v0:function(){},_abort:function(){a.abort()},___setErrNo:function(d){a.___errno_location&&(u[a.___errno_location()>>2]=d);return d},___syscall6:function(a,
|
b,c){C.infos[a]={ptr:a,adjusted:a,type:b,destructor:c,refcount:0,caught:!1,rethrown:!1};C.last=a;"uncaught_exception"in la?la.uncaught_exception++:la.uncaught_exception=1;throw a+" - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch.";},___gxx_personality_v0:function(){},_abort:function(){a.abort()},___setErrNo:function(d){a.___errno_location&&(u[a.___errno_location()>>2]=d);return d},___syscall6:function(a,
|
||||||
b){r.varargs=b;try{var c=r.getStreamFromFD();FS.close(c);return 0}catch(g){return"undefined"!==typeof FS&&g instanceof FS.ErrnoError||M(g),-g.errno}},___cxa_begin_catch:function(a){var b=C.infos[a];b&&!b.caught&&(b.caught=!0,ma.uncaught_exception--);b&&(b.rethrown=!1);C.caught.push(a);C.addRef(C.deAdjust(a));return a},___syscall146:ca,_pthread_once:va,_emscripten_memcpy_big:function(a,b,c){G.set(G.subarray(b,b+c),a);return a},_pthread_key_create:function(a,b){if(0==a)return 22;u[a>>2]=Ua;Da[Ua]=0;
|
b){r.varargs=b;try{var c=r.getStreamFromFD();FS.close(c);return 0}catch(g){return"undefined"!==typeof FS&&g instanceof FS.ErrnoError||M(g),-g.errno}},___cxa_begin_catch:function(a){var b=C.infos[a];b&&!b.caught&&(b.caught=!0,la.uncaught_exception--);b&&(b.rethrown=!1);C.caught.push(a);C.addRef(C.deAdjust(a));return a},___syscall146:ca,_pthread_once:ua,_emscripten_memcpy_big:function(a,b,c){G.set(G.subarray(b,b+c),a);return a},_pthread_key_create:function(a,b){if(0==a)return 22;u[a>>2]=Ta;Ca[Ta]=0;
|
||||||
Ua++;return 0},___syscall140:function(a,b){r.varargs=b;try{var c=r.getStreamFromFD();r.get();var d=r.get(),e=r.get(),f=r.get();FS.llseek(c,d,f);u[e>>2]=c.position;c.getdents&&0===d&&0===f&&(c.getdents=null);return 0}catch(S){return"undefined"!==typeof FS&&S instanceof FS.ErrnoError||M(S),-S.errno}},___resumeException:function(a){C.last||(C.last=a);throw a+" - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch.";
|
Ta++;return 0},___syscall140:function(a,b){r.varargs=b;try{var c=r.getStreamFromFD();r.get();var d=r.get(),e=r.get(),f=r.get();FS.llseek(c,d,f);u[e>>2]=c.position;c.getdents&&0===d&&0===f&&(c.getdents=null);return 0}catch(S){return"undefined"!==typeof FS&&S instanceof FS.ErrnoError||M(S),-S.errno}},___resumeException:function(a){C.last||(C.last=a);throw a+" - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch.";
|
||||||
},___cxa_find_matching_catch:ua,___assert_fail:function(a,b,c,e){oa=!0;throw"Assertion failed: "+t(a)+", at: "+[b?t(b):"unknown filename",c,e?t(e):"unknown function"]+" at "+ja();},___cxa_pure_virtual:function(){oa=!0;throw"Pure virtual function called!";},___cxa_allocate_exception:function(a){return la(a)},__ZSt18uncaught_exceptionv:ma,DYNAMICTOP_PTR:X,tempDoublePtr:Mb,ABORT:oa,STACKTOP:T,STACK_MAX:Ca};var mb=a.asm(a.asmGlobalArg,a.asmLibraryArg,H);a.asm=mb;var Sb=a._emscripten_bind_Decoder_GetAttributeFloat_3=
|
},___cxa_find_matching_catch:ta,___assert_fail:function(a,b,c,e){na=!0;throw"Assertion failed: "+t(a)+", at: "+[b?t(b):"unknown filename",c,e?t(e):"unknown function"]+" at "+ia();},___cxa_pure_virtual:function(){na=!0;throw"Pure virtual function called!";},___cxa_allocate_exception:function(a){return ka(a)},__ZSt18uncaught_exceptionv:la,DYNAMICTOP_PTR:Y,tempDoublePtr:Lb,ABORT:na,STACKTOP:T,STACK_MAX:Ba};var lb=a.asm(a.asmGlobalArg,a.asmLibraryArg,H);a.asm=lb;var Rb=a._emscripten_bind_Decoder_GetAttributeFloat_3=
|
||||||
function(){return a.asm._emscripten_bind_Decoder_GetAttributeFloat_3.apply(null,arguments)},Tb=a._emscripten_bind_PointAttribute_normalized_0=function(){return a.asm._emscripten_bind_PointAttribute_normalized_0.apply(null,arguments)},Ub=a._emscripten_bind_Decoder_GetAttributeFloatForAllPoints_3=function(){return a.asm._emscripten_bind_Decoder_GetAttributeFloatForAllPoints_3.apply(null,arguments)},Vb=a._emscripten_bind_DecoderBuffer_Init_2=function(){return a.asm._emscripten_bind_DecoderBuffer_Init_2.apply(null,
|
function(){return a.asm._emscripten_bind_Decoder_GetAttributeFloat_3.apply(null,arguments)},Sb=a._emscripten_bind_PointAttribute_normalized_0=function(){return a.asm._emscripten_bind_PointAttribute_normalized_0.apply(null,arguments)},Tb=a._emscripten_bind_Decoder_GetAttributeFloatForAllPoints_3=function(){return a.asm._emscripten_bind_Decoder_GetAttributeFloatForAllPoints_3.apply(null,arguments)},Ub=a._emscripten_bind_DecoderBuffer_Init_2=function(){return a.asm._emscripten_bind_DecoderBuffer_Init_2.apply(null,
|
||||||
arguments)},Wb=a._emscripten_bind_PointAttribute_size_0=function(){return a.asm._emscripten_bind_PointAttribute_size_0.apply(null,arguments)},Xb=a._emscripten_enum_draco_GeometryAttribute_Type_POSITION=function(){return a.asm._emscripten_enum_draco_GeometryAttribute_Type_POSITION.apply(null,arguments)},Pb=a._sbrk=function(){return a.asm._sbrk.apply(null,arguments)},Ob=a._memcpy=function(){return a.asm._memcpy.apply(null,arguments)};a.stackSave=function(){return a.asm.stackSave.apply(null,arguments)};
|
arguments)},Vb=a._emscripten_bind_PointAttribute_size_0=function(){return a.asm._emscripten_bind_PointAttribute_size_0.apply(null,arguments)},Wb=a._emscripten_enum_draco_GeometryAttribute_Type_POSITION=function(){return a.asm._emscripten_enum_draco_GeometryAttribute_Type_POSITION.apply(null,arguments)},Ob=a._sbrk=function(){return a.asm._sbrk.apply(null,arguments)},Nb=a._memcpy=function(){return a.asm._memcpy.apply(null,arguments)};a.stackSave=function(){return a.asm.stackSave.apply(null,arguments)};
|
||||||
var Yb=a._emscripten_enum_draco_GeometryAttribute_Type_INVALID=function(){return a.asm._emscripten_enum_draco_GeometryAttribute_Type_INVALID.apply(null,arguments)},Zb=a._emscripten_bind_Decoder_GetAttributeIdByName_2=function(){return a.asm._emscripten_bind_Decoder_GetAttributeIdByName_2.apply(null,arguments)},$b=a._emscripten_enum_draco_EncodedGeometryType_POINT_CLOUD=function(){return a.asm._emscripten_enum_draco_EncodedGeometryType_POINT_CLOUD.apply(null,arguments)},ac=a._emscripten_bind_Status_ok_0=
|
var Xb=a._emscripten_enum_draco_GeometryAttribute_Type_INVALID=function(){return a.asm._emscripten_enum_draco_GeometryAttribute_Type_INVALID.apply(null,arguments)},Yb=a._emscripten_bind_Decoder_GetAttributeIdByName_2=function(){return a.asm._emscripten_bind_Decoder_GetAttributeIdByName_2.apply(null,arguments)},Zb=a._emscripten_enum_draco_EncodedGeometryType_POINT_CLOUD=function(){return a.asm._emscripten_enum_draco_EncodedGeometryType_POINT_CLOUD.apply(null,arguments)},$b=a._emscripten_bind_Status_ok_0=
|
||||||
function(){return a.asm._emscripten_bind_Status_ok_0.apply(null,arguments)},bc=a._emscripten_bind_Mesh_num_faces_0=function(){return a.asm._emscripten_bind_Mesh_num_faces_0.apply(null,arguments)};a._emscripten_get_global_libc=function(){return a.asm._emscripten_get_global_libc.apply(null,arguments)};var cc=a._emscripten_bind_Decoder_DecodeBufferToPointCloud_2=function(){return a.asm._emscripten_bind_Decoder_DecodeBufferToPointCloud_2.apply(null,arguments)},dc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_NO_TRANSFORM=
|
function(){return a.asm._emscripten_bind_Status_ok_0.apply(null,arguments)},ac=a._emscripten_bind_Mesh_num_faces_0=function(){return a.asm._emscripten_bind_Mesh_num_faces_0.apply(null,arguments)};a._emscripten_get_global_libc=function(){return a.asm._emscripten_get_global_libc.apply(null,arguments)};var bc=a._emscripten_bind_Decoder_DecodeBufferToPointCloud_2=function(){return a.asm._emscripten_bind_Decoder_DecodeBufferToPointCloud_2.apply(null,arguments)},cc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_NO_TRANSFORM=
|
||||||
function(){return a.asm._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_NO_TRANSFORM.apply(null,arguments)};a.runPostSets=function(){return a.asm.runPostSets.apply(null,arguments)};var ec=a._emscripten_bind_Decoder_GetEncodedGeometryType_1=function(){return a.asm._emscripten_bind_Decoder_GetEncodedGeometryType_1.apply(null,arguments)};a.___cxa_can_catch=function(){return a.asm.___cxa_can_catch.apply(null,arguments)};var Ia=a._free=function(){return a.asm._free.apply(null,arguments)},fc=a._emscripten_enum_draco_EncodedGeometryType_INVALID_GEOMETRY_TYPE=
|
function(){return a.asm._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_NO_TRANSFORM.apply(null,arguments)};a.runPostSets=function(){return a.asm.runPostSets.apply(null,arguments)};var dc=a._emscripten_bind_Decoder_GetEncodedGeometryType_1=function(){return a.asm._emscripten_bind_Decoder_GetEncodedGeometryType_1.apply(null,arguments)};a.___cxa_can_catch=function(){return a.asm.___cxa_can_catch.apply(null,arguments)};var Ha=a._free=function(){return a.asm._free.apply(null,arguments)},ec=a._emscripten_enum_draco_EncodedGeometryType_INVALID_GEOMETRY_TYPE=
|
||||||
function(){return a.asm._emscripten_enum_draco_EncodedGeometryType_INVALID_GEOMETRY_TYPE.apply(null,arguments)},gc=a._emscripten_bind_GeometryAttribute___destroy___0=function(){return a.asm._emscripten_bind_GeometryAttribute___destroy___0.apply(null,arguments)},hc=a._emscripten_bind_PointAttribute_byte_stride_0=function(){return a.asm._emscripten_bind_PointAttribute_byte_stride_0.apply(null,arguments)},Ib=a._emscripten_bind_Metadata_Metadata_0=function(){return a.asm._emscripten_bind_Metadata_Metadata_0.apply(null,
|
function(){return a.asm._emscripten_enum_draco_EncodedGeometryType_INVALID_GEOMETRY_TYPE.apply(null,arguments)},fc=a._emscripten_bind_GeometryAttribute___destroy___0=function(){return a.asm._emscripten_bind_GeometryAttribute___destroy___0.apply(null,arguments)},gc=a._emscripten_bind_PointAttribute_byte_stride_0=function(){return a.asm._emscripten_bind_PointAttribute_byte_stride_0.apply(null,arguments)},Hb=a._emscripten_bind_Metadata_Metadata_0=function(){return a.asm._emscripten_bind_Metadata_Metadata_0.apply(null,
|
||||||
arguments)},ic=a._emscripten_bind_AttributeQuantizationTransform_min_value_1=function(){return a.asm._emscripten_bind_AttributeQuantizationTransform_min_value_1.apply(null,arguments)},Fb=a._emscripten_bind_Decoder_Decoder_0=function(){return a.asm._emscripten_bind_Decoder_Decoder_0.apply(null,arguments)},jc=a._emscripten_bind_MetadataQuerier_GetStringEntry_2=function(){return a.asm._emscripten_bind_MetadataQuerier_GetStringEntry_2.apply(null,arguments)},kc=a._emscripten_bind_MetadataQuerier_GetIntEntry_2=
|
arguments)},hc=a._emscripten_bind_AttributeQuantizationTransform_min_value_1=function(){return a.asm._emscripten_bind_AttributeQuantizationTransform_min_value_1.apply(null,arguments)},Eb=a._emscripten_bind_Decoder_Decoder_0=function(){return a.asm._emscripten_bind_Decoder_Decoder_0.apply(null,arguments)},ic=a._emscripten_bind_MetadataQuerier_GetStringEntry_2=function(){return a.asm._emscripten_bind_MetadataQuerier_GetStringEntry_2.apply(null,arguments)},jc=a._emscripten_bind_MetadataQuerier_GetIntEntry_2=
|
||||||
function(){return a.asm._emscripten_bind_MetadataQuerier_GetIntEntry_2.apply(null,arguments)},lc=a._emscripten_bind_Decoder___destroy___0=function(){return a.asm._emscripten_bind_Decoder___destroy___0.apply(null,arguments)},mc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_OCTAHEDRON_TRANSFORM=function(){return a.asm._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_OCTAHEDRON_TRANSFORM.apply(null,arguments)};a.getTempRet0=function(){return a.asm.getTempRet0.apply(null,arguments)};
|
function(){return a.asm._emscripten_bind_MetadataQuerier_GetIntEntry_2.apply(null,arguments)},kc=a._emscripten_bind_Decoder___destroy___0=function(){return a.asm._emscripten_bind_Decoder___destroy___0.apply(null,arguments)},lc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_OCTAHEDRON_TRANSFORM=function(){return a.asm._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_OCTAHEDRON_TRANSFORM.apply(null,arguments)};a.getTempRet0=function(){return a.asm.getTempRet0.apply(null,arguments)};
|
||||||
a.setThrew=function(){return a.asm.setThrew.apply(null,arguments)};var nc=a._emscripten_bind_MetadataQuerier_HasStringEntry_2=function(){return a.asm._emscripten_bind_MetadataQuerier_HasStringEntry_2.apply(null,arguments)},oc=a._emscripten_bind_AttributeTransformData___destroy___0=function(){return a.asm._emscripten_bind_AttributeTransformData___destroy___0.apply(null,arguments)},pc=a._emscripten_bind_PointAttribute_num_components_0=function(){return a.asm._emscripten_bind_PointAttribute_num_components_0.apply(null,
|
a.setThrew=function(){return a.asm.setThrew.apply(null,arguments)};var mc=a._emscripten_bind_MetadataQuerier_HasStringEntry_2=function(){return a.asm._emscripten_bind_MetadataQuerier_HasStringEntry_2.apply(null,arguments)},nc=a._emscripten_bind_AttributeTransformData___destroy___0=function(){return a.asm._emscripten_bind_AttributeTransformData___destroy___0.apply(null,arguments)},oc=a._emscripten_bind_PointAttribute_num_components_0=function(){return a.asm._emscripten_bind_PointAttribute_num_components_0.apply(null,
|
||||||
arguments)};a.___cxa_is_pointer_type=function(){return a.asm.___cxa_is_pointer_type.apply(null,arguments)};var zb=a._emscripten_bind_AttributeTransformData_AttributeTransformData_0=function(){return a.asm._emscripten_bind_AttributeTransformData_AttributeTransformData_0.apply(null,arguments)},qc=a._emscripten_bind_AttributeQuantizationTransform___destroy___0=function(){return a.asm._emscripten_bind_AttributeQuantizationTransform___destroy___0.apply(null,arguments)};a.stackAlloc=function(){return a.asm.stackAlloc.apply(null,
|
arguments)};a.___cxa_is_pointer_type=function(){return a.asm.___cxa_is_pointer_type.apply(null,arguments)};var yb=a._emscripten_bind_AttributeTransformData_AttributeTransformData_0=function(){return a.asm._emscripten_bind_AttributeTransformData_AttributeTransformData_0.apply(null,arguments)},pc=a._emscripten_bind_AttributeQuantizationTransform___destroy___0=function(){return a.asm._emscripten_bind_AttributeQuantizationTransform___destroy___0.apply(null,arguments)};a.stackAlloc=function(){return a.asm.stackAlloc.apply(null,
|
||||||
arguments)};var rc=a._emscripten_bind_DracoInt32Array___destroy___0=function(){return a.asm._emscripten_bind_DracoInt32Array___destroy___0.apply(null,arguments)},sc=a._emscripten_bind_Mesh_num_points_0=function(){return a.asm._emscripten_bind_Mesh_num_points_0.apply(null,arguments)},tc=a._emscripten_bind_PointCloud_num_attributes_0=function(){return a.asm._emscripten_bind_PointCloud_num_attributes_0.apply(null,arguments)},Gb=a._emscripten_bind_Mesh_Mesh_0=function(){return a.asm._emscripten_bind_Mesh_Mesh_0.apply(null,
|
arguments)};var qc=a._emscripten_bind_DracoInt32Array___destroy___0=function(){return a.asm._emscripten_bind_DracoInt32Array___destroy___0.apply(null,arguments)},rc=a._emscripten_bind_Mesh_num_points_0=function(){return a.asm._emscripten_bind_Mesh_num_points_0.apply(null,arguments)},sc=a._emscripten_bind_PointCloud_num_attributes_0=function(){return a.asm._emscripten_bind_PointCloud_num_attributes_0.apply(null,arguments)},Fb=a._emscripten_bind_Mesh_Mesh_0=function(){return a.asm._emscripten_bind_Mesh_Mesh_0.apply(null,
|
||||||
arguments)},Bb=a._emscripten_bind_MetadataQuerier_MetadataQuerier_0=function(){return a.asm._emscripten_bind_MetadataQuerier_MetadataQuerier_0.apply(null,arguments)},uc=a._emscripten_bind_Decoder_GetAttributeIdByMetadataEntry_3=function(){return a.asm._emscripten_bind_Decoder_GetAttributeIdByMetadataEntry_3.apply(null,arguments)},vc=a._emscripten_bind_MetadataQuerier_HasDoubleEntry_2=function(){return a.asm._emscripten_bind_MetadataQuerier_HasDoubleEntry_2.apply(null,arguments)},wc=a._emscripten_bind_MetadataQuerier_GetDoubleEntry_2=
|
arguments)},Ab=a._emscripten_bind_MetadataQuerier_MetadataQuerier_0=function(){return a.asm._emscripten_bind_MetadataQuerier_MetadataQuerier_0.apply(null,arguments)},tc=a._emscripten_bind_Decoder_GetAttributeByUniqueId_2=function(){return a.asm._emscripten_bind_Decoder_GetAttributeByUniqueId_2.apply(null,arguments)},uc=a._emscripten_bind_Decoder_GetAttributeIdByMetadataEntry_3=function(){return a.asm._emscripten_bind_Decoder_GetAttributeIdByMetadataEntry_3.apply(null,arguments)},vc=a._emscripten_bind_MetadataQuerier_HasDoubleEntry_2=
|
||||||
function(){return a.asm._emscripten_bind_MetadataQuerier_GetDoubleEntry_2.apply(null,arguments)},xc=a._emscripten_bind_Mesh_num_attributes_0=function(){return a.asm._emscripten_bind_Mesh_num_attributes_0.apply(null,arguments)},yc=a._emscripten_bind_AttributeOctahedronTransform_quantization_bits_0=function(){return a.asm._emscripten_bind_AttributeOctahedronTransform_quantization_bits_0.apply(null,arguments)},zc=a._emscripten_bind_AttributeOctahedronTransform___destroy___0=function(){return a.asm._emscripten_bind_AttributeOctahedronTransform___destroy___0.apply(null,
|
function(){return a.asm._emscripten_bind_MetadataQuerier_HasDoubleEntry_2.apply(null,arguments)},wc=a._emscripten_bind_MetadataQuerier_GetDoubleEntry_2=function(){return a.asm._emscripten_bind_MetadataQuerier_GetDoubleEntry_2.apply(null,arguments)},xc=a._emscripten_bind_Mesh_num_attributes_0=function(){return a.asm._emscripten_bind_Mesh_num_attributes_0.apply(null,arguments)},yc=a._emscripten_bind_AttributeOctahedronTransform_quantization_bits_0=function(){return a.asm._emscripten_bind_AttributeOctahedronTransform_quantization_bits_0.apply(null,
|
||||||
arguments)},Rb=a._llvm_bswap_i32=function(){return a.asm._llvm_bswap_i32.apply(null,arguments)},Ac=a._emscripten_bind_Decoder_GetAttributeMetadata_2=function(){return a.asm._emscripten_bind_Decoder_GetAttributeMetadata_2.apply(null,arguments)},Bc=a._emscripten_bind_PointAttribute_unique_id_0=function(){return a.asm._emscripten_bind_PointAttribute_unique_id_0.apply(null,arguments)};a.establishStackSpace=function(){return a.asm.establishStackSpace.apply(null,arguments)};var Cc=a._emscripten_enum_draco_StatusCode_IO_ERROR=
|
arguments)},zc=a._emscripten_bind_AttributeOctahedronTransform___destroy___0=function(){return a.asm._emscripten_bind_AttributeOctahedronTransform___destroy___0.apply(null,arguments)},Qb=a._llvm_bswap_i32=function(){return a.asm._llvm_bswap_i32.apply(null,arguments)},Ac=a._emscripten_bind_Decoder_GetAttributeMetadata_2=function(){return a.asm._emscripten_bind_Decoder_GetAttributeMetadata_2.apply(null,arguments)},Bc=a._emscripten_bind_PointAttribute_unique_id_0=function(){return a.asm._emscripten_bind_PointAttribute_unique_id_0.apply(null,
|
||||||
function(){return a.asm._emscripten_enum_draco_StatusCode_IO_ERROR.apply(null,arguments)},Dc=a._emscripten_bind_MetadataQuerier_HasIntEntry_2=function(){return a.asm._emscripten_bind_MetadataQuerier_HasIntEntry_2.apply(null,arguments)},Ec=a._emscripten_bind_Decoder_GetTriangleStripsFromMesh_2=function(){return a.asm._emscripten_bind_Decoder_GetTriangleStripsFromMesh_2.apply(null,arguments)},Fc=a._emscripten_enum_draco_GeometryAttribute_Type_TEX_COORD=function(){return a.asm._emscripten_enum_draco_GeometryAttribute_Type_TEX_COORD.apply(null,
|
arguments)};a.establishStackSpace=function(){return a.asm.establishStackSpace.apply(null,arguments)};var Cc=a._emscripten_enum_draco_StatusCode_IO_ERROR=function(){return a.asm._emscripten_enum_draco_StatusCode_IO_ERROR.apply(null,arguments)},Dc=a._emscripten_bind_MetadataQuerier_HasIntEntry_2=function(){return a.asm._emscripten_bind_MetadataQuerier_HasIntEntry_2.apply(null,arguments)},Ec=a._emscripten_bind_Decoder_GetTriangleStripsFromMesh_2=function(){return a.asm._emscripten_bind_Decoder_GetTriangleStripsFromMesh_2.apply(null,
|
||||||
arguments)},Eb=a._emscripten_bind_DecoderBuffer_DecoderBuffer_0=function(){return a.asm._emscripten_bind_DecoderBuffer_DecoderBuffer_0.apply(null,arguments)},Gc=a._emscripten_bind_DracoInt32Array_size_0=function(){return a.asm._emscripten_bind_DracoInt32Array_size_0.apply(null,arguments)},Hc=a._emscripten_bind_Decoder_SkipAttributeTransform_1=function(){return a.asm._emscripten_bind_Decoder_SkipAttributeTransform_1.apply(null,arguments)},Ic=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_QUANTIZATION_TRANSFORM=
|
arguments)},Fc=a._emscripten_enum_draco_GeometryAttribute_Type_TEX_COORD=function(){return a.asm._emscripten_enum_draco_GeometryAttribute_Type_TEX_COORD.apply(null,arguments)},Db=a._emscripten_bind_DecoderBuffer_DecoderBuffer_0=function(){return a.asm._emscripten_bind_DecoderBuffer_DecoderBuffer_0.apply(null,arguments)},Gc=a._emscripten_bind_DracoInt32Array_size_0=function(){return a.asm._emscripten_bind_DracoInt32Array_size_0.apply(null,arguments)},Hc=a._emscripten_bind_Decoder_SkipAttributeTransform_1=
|
||||||
function(){return a.asm._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_QUANTIZATION_TRANSFORM.apply(null,arguments)},Jc=a._emscripten_bind_Decoder_GetAttributeIntForAllPoints_3=function(){return a.asm._emscripten_bind_Decoder_GetAttributeIntForAllPoints_3.apply(null,arguments)},Kc=a._emscripten_enum_draco_StatusCode_ERROR=function(){return a.asm._emscripten_enum_draco_StatusCode_ERROR.apply(null,arguments)},Lc=a._emscripten_bind_AttributeQuantizationTransform_quantization_bits_0=function(){return a.asm._emscripten_bind_AttributeQuantizationTransform_quantization_bits_0.apply(null,
|
function(){return a.asm._emscripten_bind_Decoder_SkipAttributeTransform_1.apply(null,arguments)},Ic=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_QUANTIZATION_TRANSFORM=function(){return a.asm._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_QUANTIZATION_TRANSFORM.apply(null,arguments)},Jc=a._emscripten_bind_Decoder_GetAttributeIntForAllPoints_3=function(){return a.asm._emscripten_bind_Decoder_GetAttributeIntForAllPoints_3.apply(null,arguments)},Kc=a._emscripten_enum_draco_StatusCode_ERROR=
|
||||||
arguments)},Mc=a._emscripten_enum_draco_StatusCode_INVALID_PARAMETER=function(){return a.asm._emscripten_enum_draco_StatusCode_INVALID_PARAMETER.apply(null,arguments)},Nc=a._emscripten_enum_draco_GeometryAttribute_Type_COLOR=function(){return a.asm._emscripten_enum_draco_GeometryAttribute_Type_COLOR.apply(null,arguments)},Oc=a._emscripten_bind_VoidPtr___destroy___0=function(){return a.asm._emscripten_bind_VoidPtr___destroy___0.apply(null,arguments)},Nb=a._memset=function(){return a.asm._memset.apply(null,
|
function(){return a.asm._emscripten_enum_draco_StatusCode_ERROR.apply(null,arguments)},Lc=a._emscripten_bind_AttributeQuantizationTransform_quantization_bits_0=function(){return a.asm._emscripten_bind_AttributeQuantizationTransform_quantization_bits_0.apply(null,arguments)},Mc=a._emscripten_enum_draco_StatusCode_INVALID_PARAMETER=function(){return a.asm._emscripten_enum_draco_StatusCode_INVALID_PARAMETER.apply(null,arguments)},Nc=a._emscripten_enum_draco_GeometryAttribute_Type_COLOR=function(){return a.asm._emscripten_enum_draco_GeometryAttribute_Type_COLOR.apply(null,
|
||||||
arguments)},Pc=a._emscripten_bind_PointAttribute_attribute_type_0=function(){return a.asm._emscripten_bind_PointAttribute_attribute_type_0.apply(null,arguments)},Qc=a._emscripten_bind_MetadataQuerier___destroy___0=function(){return a.asm._emscripten_bind_MetadataQuerier___destroy___0.apply(null,arguments)},Rc=a._emscripten_bind_DracoInt32Array_GetValue_1=function(){return a.asm._emscripten_bind_DracoInt32Array_GetValue_1.apply(null,arguments)},Sc=a._emscripten_bind_DecoderBuffer___destroy___0=function(){return a.asm._emscripten_bind_DecoderBuffer___destroy___0.apply(null,
|
arguments)},Oc=a._emscripten_bind_VoidPtr___destroy___0=function(){return a.asm._emscripten_bind_VoidPtr___destroy___0.apply(null,arguments)},Mb=a._memset=function(){return a.asm._memset.apply(null,arguments)},Pc=a._emscripten_bind_PointAttribute_attribute_type_0=function(){return a.asm._emscripten_bind_PointAttribute_attribute_type_0.apply(null,arguments)},Qc=a._emscripten_bind_MetadataQuerier___destroy___0=function(){return a.asm._emscripten_bind_MetadataQuerier___destroy___0.apply(null,arguments)},
|
||||||
arguments)},Tc=a._emscripten_bind_Decoder_GetAttribute_2=function(){return a.asm._emscripten_bind_Decoder_GetAttribute_2.apply(null,arguments)},Uc=a._emscripten_enum_draco_EncodedGeometryType_TRIANGULAR_MESH=function(){return a.asm._emscripten_enum_draco_EncodedGeometryType_TRIANGULAR_MESH.apply(null,arguments)};a.setTempRet0=function(){return a.asm.setTempRet0.apply(null,arguments)};var Hb=a._emscripten_bind_DracoInt32Array_DracoInt32Array_0=function(){return a.asm._emscripten_bind_DracoInt32Array_DracoInt32Array_0.apply(null,
|
Rc=a._emscripten_bind_DracoInt32Array_GetValue_1=function(){return a.asm._emscripten_bind_DracoInt32Array_GetValue_1.apply(null,arguments)},Sc=a._emscripten_bind_DecoderBuffer___destroy___0=function(){return a.asm._emscripten_bind_DecoderBuffer___destroy___0.apply(null,arguments)},Tc=a._emscripten_bind_Decoder_GetAttribute_2=function(){return a.asm._emscripten_bind_Decoder_GetAttribute_2.apply(null,arguments)},Uc=a._emscripten_bind_PointCloud___destroy___0=function(){return a.asm._emscripten_bind_PointCloud___destroy___0.apply(null,
|
||||||
arguments)},Vc=a._emscripten_enum_draco_StatusCode_UNKNOWN_VERSION=function(){return a.asm._emscripten_enum_draco_StatusCode_UNKNOWN_VERSION.apply(null,arguments)},Wc=a._emscripten_bind_DracoFloat32Array___destroy___0=function(){return a.asm._emscripten_bind_DracoFloat32Array___destroy___0.apply(null,arguments)},Xc=a._emscripten_bind_PointCloud_num_points_0=function(){return a.asm._emscripten_bind_PointCloud_num_points_0.apply(null,arguments)},Yc=a._emscripten_bind_PointCloud___destroy___0=function(){return a.asm._emscripten_bind_PointCloud___destroy___0.apply(null,
|
arguments)};a.setTempRet0=function(){return a.asm.setTempRet0.apply(null,arguments)};var Gb=a._emscripten_bind_DracoInt32Array_DracoInt32Array_0=function(){return a.asm._emscripten_bind_DracoInt32Array_DracoInt32Array_0.apply(null,arguments)},Vc=a._emscripten_enum_draco_StatusCode_UNKNOWN_VERSION=function(){return a.asm._emscripten_enum_draco_StatusCode_UNKNOWN_VERSION.apply(null,arguments)},Wc=a._emscripten_bind_DracoFloat32Array___destroy___0=function(){return a.asm._emscripten_bind_DracoFloat32Array___destroy___0.apply(null,
|
||||||
arguments)},Db=a._emscripten_bind_GeometryAttribute_GeometryAttribute_0=function(){return a.asm._emscripten_bind_GeometryAttribute_GeometryAttribute_0.apply(null,arguments)},Zc=a._emscripten_bind_Decoder_GetFaceFromMesh_3=function(){return a.asm._emscripten_bind_Decoder_GetFaceFromMesh_3.apply(null,arguments)},$c=a._emscripten_bind_PointAttribute_data_type_0=function(){return a.asm._emscripten_bind_PointAttribute_data_type_0.apply(null,arguments)},ad=a._emscripten_bind_DracoFloat32Array_size_0=function(){return a.asm._emscripten_bind_DracoFloat32Array_size_0.apply(null,
|
arguments)},Xc=a._emscripten_bind_PointCloud_num_points_0=function(){return a.asm._emscripten_bind_PointCloud_num_points_0.apply(null,arguments)},Yc=a._emscripten_enum_draco_EncodedGeometryType_TRIANGULAR_MESH=function(){return a.asm._emscripten_enum_draco_EncodedGeometryType_TRIANGULAR_MESH.apply(null,arguments)},Cb=a._emscripten_bind_GeometryAttribute_GeometryAttribute_0=function(){return a.asm._emscripten_bind_GeometryAttribute_GeometryAttribute_0.apply(null,arguments)},Zc=a._emscripten_bind_Decoder_GetFaceFromMesh_3=
|
||||||
arguments)},bd=a._emscripten_bind_AttributeOctahedronTransform_InitFromAttribute_1=function(){return a.asm._emscripten_bind_AttributeOctahedronTransform_InitFromAttribute_1.apply(null,arguments)},la=a._malloc=function(){return a.asm._malloc.apply(null,arguments)},cd=a._emscripten_bind_PointAttribute_GetAttributeTransformData_0=function(){return a.asm._emscripten_bind_PointAttribute_GetAttributeTransformData_0.apply(null,arguments)},dd=a._emscripten_bind_PointAttribute_byte_offset_0=function(){return a.asm._emscripten_bind_PointAttribute_byte_offset_0.apply(null,
|
function(){return a.asm._emscripten_bind_Decoder_GetFaceFromMesh_3.apply(null,arguments)},$c=a._emscripten_bind_PointAttribute_data_type_0=function(){return a.asm._emscripten_bind_PointAttribute_data_type_0.apply(null,arguments)},ad=a._emscripten_bind_DracoFloat32Array_size_0=function(){return a.asm._emscripten_bind_DracoFloat32Array_size_0.apply(null,arguments)},bd=a._emscripten_bind_AttributeOctahedronTransform_InitFromAttribute_1=function(){return a.asm._emscripten_bind_AttributeOctahedronTransform_InitFromAttribute_1.apply(null,
|
||||||
arguments)},Jb=a._emscripten_replace_memory=function(){return a.asm._emscripten_replace_memory.apply(null,arguments)},Qb=a._memmove=function(){return a.asm._memmove.apply(null,arguments)},wb=a._emscripten_bind_PointCloud_PointCloud_0=function(){return a.asm._emscripten_bind_PointCloud_PointCloud_0.apply(null,arguments)},ed=a._emscripten_bind_Status_error_msg_0=function(){return a.asm._emscripten_bind_Status_error_msg_0.apply(null,arguments)},fd=a._emscripten_bind_Mesh___destroy___0=function(){return a.asm._emscripten_bind_Mesh___destroy___0.apply(null,
|
arguments)},ka=a._malloc=function(){return a.asm._malloc.apply(null,arguments)},cd=a._emscripten_bind_PointAttribute_GetAttributeTransformData_0=function(){return a.asm._emscripten_bind_PointAttribute_GetAttributeTransformData_0.apply(null,arguments)},dd=a._emscripten_bind_PointAttribute_byte_offset_0=function(){return a.asm._emscripten_bind_PointAttribute_byte_offset_0.apply(null,arguments)},Ib=a._emscripten_replace_memory=function(){return a.asm._emscripten_replace_memory.apply(null,arguments)},
|
||||||
arguments)},gd=a._emscripten_bind_Metadata___destroy___0=function(){return a.asm._emscripten_bind_Metadata___destroy___0.apply(null,arguments)},hd=a._emscripten_bind_Status___destroy___0=function(){return a.asm._emscripten_bind_Status___destroy___0.apply(null,arguments)},id=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_INVALID_TRANSFORM=function(){return a.asm._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_INVALID_TRANSFORM.apply(null,arguments)},Ab=a._emscripten_bind_AttributeQuantizationTransform_AttributeQuantizationTransform_0=
|
Pb=a._memmove=function(){return a.asm._memmove.apply(null,arguments)},vb=a._emscripten_bind_PointCloud_PointCloud_0=function(){return a.asm._emscripten_bind_PointCloud_PointCloud_0.apply(null,arguments)},ed=a._emscripten_bind_Status_error_msg_0=function(){return a.asm._emscripten_bind_Status_error_msg_0.apply(null,arguments)},fd=a._emscripten_bind_Mesh___destroy___0=function(){return a.asm._emscripten_bind_Mesh___destroy___0.apply(null,arguments)},gd=a._emscripten_bind_Metadata___destroy___0=function(){return a.asm._emscripten_bind_Metadata___destroy___0.apply(null,
|
||||||
function(){return a.asm._emscripten_bind_AttributeQuantizationTransform_AttributeQuantizationTransform_0.apply(null,arguments)},jd=a._emscripten_bind_AttributeQuantizationTransform_range_0=function(){return a.asm._emscripten_bind_AttributeQuantizationTransform_range_0.apply(null,arguments)},kd=a._emscripten_bind_Decoder_GetAttributeId_2=function(){return a.asm._emscripten_bind_Decoder_GetAttributeId_2.apply(null,arguments)},ld=a._emscripten_enum_draco_StatusCode_OK=function(){return a.asm._emscripten_enum_draco_StatusCode_OK.apply(null,
|
arguments)},hd=a._emscripten_bind_Status___destroy___0=function(){return a.asm._emscripten_bind_Status___destroy___0.apply(null,arguments)},id=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_INVALID_TRANSFORM=function(){return a.asm._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_INVALID_TRANSFORM.apply(null,arguments)},zb=a._emscripten_bind_AttributeQuantizationTransform_AttributeQuantizationTransform_0=function(){return a.asm._emscripten_bind_AttributeQuantizationTransform_AttributeQuantizationTransform_0.apply(null,
|
||||||
arguments)},md=a._emscripten_bind_AttributeTransformData_transform_type_0=function(){return a.asm._emscripten_bind_AttributeTransformData_transform_type_0.apply(null,arguments)},nd=a._emscripten_bind_Status_code_0=function(){return a.asm._emscripten_bind_Status_code_0.apply(null,arguments)},xb=a._emscripten_bind_AttributeOctahedronTransform_AttributeOctahedronTransform_0=function(){return a.asm._emscripten_bind_AttributeOctahedronTransform_AttributeOctahedronTransform_0.apply(null,arguments)},Cb=
|
arguments)},jd=a._emscripten_bind_AttributeQuantizationTransform_range_0=function(){return a.asm._emscripten_bind_AttributeQuantizationTransform_range_0.apply(null,arguments)},kd=a._emscripten_bind_Decoder_GetAttributeId_2=function(){return a.asm._emscripten_bind_Decoder_GetAttributeId_2.apply(null,arguments)},ld=a._emscripten_enum_draco_StatusCode_OK=function(){return a.asm._emscripten_enum_draco_StatusCode_OK.apply(null,arguments)},md=a._emscripten_bind_AttributeTransformData_transform_type_0=function(){return a.asm._emscripten_bind_AttributeTransformData_transform_type_0.apply(null,
|
||||||
a._emscripten_bind_DracoFloat32Array_DracoFloat32Array_0=function(){return a.asm._emscripten_bind_DracoFloat32Array_DracoFloat32Array_0.apply(null,arguments)},od=a._emscripten_enum_draco_GeometryAttribute_Type_GENERIC=function(){return a.asm._emscripten_enum_draco_GeometryAttribute_Type_GENERIC.apply(null,arguments)},pd=a._emscripten_bind_Decoder_DecodeBufferToMesh_2=function(){return a.asm._emscripten_bind_Decoder_DecodeBufferToMesh_2.apply(null,arguments)},qd=a._emscripten_bind_DracoFloat32Array_GetValue_1=
|
arguments)},nd=a._emscripten_bind_Status_code_0=function(){return a.asm._emscripten_bind_Status_code_0.apply(null,arguments)},wb=a._emscripten_bind_AttributeOctahedronTransform_AttributeOctahedronTransform_0=function(){return a.asm._emscripten_bind_AttributeOctahedronTransform_AttributeOctahedronTransform_0.apply(null,arguments)},Bb=a._emscripten_bind_DracoFloat32Array_DracoFloat32Array_0=function(){return a.asm._emscripten_bind_DracoFloat32Array_DracoFloat32Array_0.apply(null,arguments)},od=a._emscripten_enum_draco_GeometryAttribute_Type_GENERIC=
|
||||||
function(){return a.asm._emscripten_bind_DracoFloat32Array_GetValue_1.apply(null,arguments)},yb=a._emscripten_bind_PointAttribute_PointAttribute_0=function(){return a.asm._emscripten_bind_PointAttribute_PointAttribute_0.apply(null,arguments)},rd=a._emscripten_bind_Decoder_GetMetadata_1=function(){return a.asm._emscripten_bind_Decoder_GetMetadata_1.apply(null,arguments)},sd=a._emscripten_enum_draco_GeometryAttribute_Type_NORMAL=function(){return a.asm._emscripten_enum_draco_GeometryAttribute_Type_NORMAL.apply(null,
|
function(){return a.asm._emscripten_enum_draco_GeometryAttribute_Type_GENERIC.apply(null,arguments)},pd=a._emscripten_bind_Decoder_DecodeBufferToMesh_2=function(){return a.asm._emscripten_bind_Decoder_DecodeBufferToMesh_2.apply(null,arguments)},qd=a._emscripten_bind_DracoFloat32Array_GetValue_1=function(){return a.asm._emscripten_bind_DracoFloat32Array_GetValue_1.apply(null,arguments)},xb=a._emscripten_bind_PointAttribute_PointAttribute_0=function(){return a.asm._emscripten_bind_PointAttribute_PointAttribute_0.apply(null,
|
||||||
arguments)};a.stackRestore=function(){return a.asm.stackRestore.apply(null,arguments)};var td=a._emscripten_bind_AttributeQuantizationTransform_InitFromAttribute_1=function(){return a.asm._emscripten_bind_AttributeQuantizationTransform_InitFromAttribute_1.apply(null,arguments)},ud=a._emscripten_bind_PointAttribute___destroy___0=function(){return a.asm._emscripten_bind_PointAttribute___destroy___0.apply(null,arguments)},vd=a._emscripten_enum_draco_StatusCode_UNSUPPORTED_VERSION=function(){return a.asm._emscripten_enum_draco_StatusCode_UNSUPPORTED_VERSION.apply(null,
|
arguments)},rd=a._emscripten_bind_Decoder_GetMetadata_1=function(){return a.asm._emscripten_bind_Decoder_GetMetadata_1.apply(null,arguments)},sd=a._emscripten_enum_draco_GeometryAttribute_Type_NORMAL=function(){return a.asm._emscripten_enum_draco_GeometryAttribute_Type_NORMAL.apply(null,arguments)};a.stackRestore=function(){return a.asm.stackRestore.apply(null,arguments)};var td=a._emscripten_bind_AttributeQuantizationTransform_InitFromAttribute_1=function(){return a.asm._emscripten_bind_AttributeQuantizationTransform_InitFromAttribute_1.apply(null,
|
||||||
arguments)};a.dynCall_iiii=function(){return a.asm.dynCall_iiii.apply(null,arguments)};a.dynCall_viiiii=function(){return a.asm.dynCall_viiiii.apply(null,arguments)};a.dynCall_vi=function(){return a.asm.dynCall_vi.apply(null,arguments)};a.dynCall_vii=function(){return a.asm.dynCall_vii.apply(null,arguments)};a.dynCall_iiiiiii=function(){return a.asm.dynCall_iiiiiii.apply(null,arguments)};a.dynCall_ii=function(){return a.asm.dynCall_ii.apply(null,arguments)};a.dynCall_viii=function(){return a.asm.dynCall_viii.apply(null,
|
arguments)},ud=a._emscripten_bind_PointAttribute___destroy___0=function(){return a.asm._emscripten_bind_PointAttribute___destroy___0.apply(null,arguments)},vd=a._emscripten_enum_draco_StatusCode_UNSUPPORTED_VERSION=function(){return a.asm._emscripten_enum_draco_StatusCode_UNSUPPORTED_VERSION.apply(null,arguments)};a.dynCall_iiii=function(){return a.asm.dynCall_iiii.apply(null,arguments)};a.dynCall_viiiii=function(){return a.asm.dynCall_viiiii.apply(null,arguments)};a.dynCall_vi=function(){return a.asm.dynCall_vi.apply(null,
|
||||||
arguments)};a.dynCall_v=function(){return a.asm.dynCall_v.apply(null,arguments)};a.dynCall_viiiiii=function(){return a.asm.dynCall_viiiiii.apply(null,arguments)};a.dynCall_iii=function(){return a.asm.dynCall_iii.apply(null,arguments)};a.dynCall_viiii=function(){return a.asm.dynCall_viiii.apply(null,arguments)};n.stackAlloc=a.stackAlloc;n.stackSave=a.stackSave;n.stackRestore=a.stackRestore;n.establishStackSpace=a.establishStackSpace;n.setTempRet0=a.setTempRet0;n.getTempRet0=a.getTempRet0;a.asm=mb;
|
arguments)};a.dynCall_vii=function(){return a.asm.dynCall_vii.apply(null,arguments)};a.dynCall_iiiiiii=function(){return a.asm.dynCall_iiiiiii.apply(null,arguments)};a.dynCall_ii=function(){return a.asm.dynCall_ii.apply(null,arguments)};a.dynCall_viii=function(){return a.asm.dynCall_viii.apply(null,arguments)};a.dynCall_v=function(){return a.asm.dynCall_v.apply(null,arguments)};a.dynCall_viiiiii=function(){return a.asm.dynCall_viiiiii.apply(null,arguments)};a.dynCall_iii=function(){return a.asm.dynCall_iii.apply(null,
|
||||||
if(U)if("function"===typeof a.locateFile?U=a.locateFile(U):a.memoryInitializerPrefixURL&&(U=a.memoryInitializerPrefixURL+U),pa||Ba){var wd=a.readBinary(U);G.set(wd,n.GLOBAL_BASE)}else{var ob=function(){a.readAsync(U,nb,function(){throw"could not load memory initializer "+U;})};Za("memory initializer");var nb=function(d){d.byteLength&&(d=new Uint8Array(d));G.set(d,n.GLOBAL_BASE);a.memoryInitializerRequest&&delete a.memoryInitializerRequest.response;$a("memory initializer")};if(a.memoryInitializerRequest){var pb=
|
arguments)};a.dynCall_viiii=function(){return a.asm.dynCall_viiii.apply(null,arguments)};n.stackAlloc=a.stackAlloc;n.stackSave=a.stackSave;n.stackRestore=a.stackRestore;n.establishStackSpace=a.establishStackSpace;n.setTempRet0=a.setTempRet0;n.getTempRet0=a.getTempRet0;a.asm=lb;if(U)if("function"===typeof a.locateFile?U=a.locateFile(U):a.memoryInitializerPrefixURL&&(U=a.memoryInitializerPrefixURL+U),oa||Aa){var wd=a.readBinary(U);G.set(wd,n.GLOBAL_BASE)}else{var nb=function(){a.readAsync(U,mb,function(){throw"could not load memory initializer "+
|
||||||
function(){var d=a.memoryInitializerRequest;200!==d.status&&0!==d.status?(console.warn("a problem seems to have happened with Module.memoryInitializerRequest, status: "+d.status+", retrying "+U),ob()):nb(d.response)};a.memoryInitializerRequest.response?setTimeout(pb,0):a.memoryInitializerRequest.addEventListener("load",pb)}else ob()}a.then=function(d){if(a.calledRun)d(a);else{var b=a.onRuntimeInitialized;a.onRuntimeInitialized=function(){b&&b();d(a)}}return a};na.prototype=Error();na.prototype.constructor=
|
U;})};Ya("memory initializer");var mb=function(d){d.byteLength&&(d=new Uint8Array(d));G.set(d,n.GLOBAL_BASE);a.memoryInitializerRequest&&delete a.memoryInitializerRequest.response;Za("memory initializer")};if(a.memoryInitializerRequest){var ob=function(){var d=a.memoryInitializerRequest;200!==d.status&&0!==d.status?(console.warn("a problem seems to have happened with Module.memoryInitializerRequest, status: "+d.status+", retrying "+U),nb()):mb(d.response)};a.memoryInitializerRequest.response?setTimeout(ob,
|
||||||
na;var vb,eb=null;ta=function b(){a.calledRun||La();a.calledRun||(ta=b)};a.callMain=a.callMain=function(b){function c(){for(var a=0;3>a;a++)f.push(0)}b=b||[];Aa||(Aa=!0,ka(Ma));var e=b.length+1,f=[R(ra(a.thisProgram),"i8",0)];c();for(var h=0;h<e-1;h+=1)f.push(R(ra(b[h]),"i8",0)),c();f.push(0);f=R(f,"i32",0);try{var k=a._main(e,f,0);gb(k,!0)}catch(y){y instanceof na||("SimulateInfiniteLoop"==y?a.noExitRuntime=!0:((b=y)&&"object"===typeof y&&y.stack&&(b=[y,y.stack]),a.printErr("exception thrown: "+
|
0):a.memoryInitializerRequest.addEventListener("load",ob)}else nb()}a.then=function(d){if(a.calledRun)d(a);else{var b=a.onRuntimeInitialized;a.onRuntimeInitialized=function(){b&&b();d(a)}}return a};ma.prototype=Error();ma.prototype.constructor=ma;var ub,db=null;sa=function b(){a.calledRun||Ka();a.calledRun||(sa=b)};a.callMain=a.callMain=function(b){function c(){for(var a=0;3>a;a++)f.push(0)}b=b||[];za||(za=!0,ja(La));var e=b.length+1,f=[R(qa(a.thisProgram),"i8",0)];c();for(var h=0;h<e-1;h+=1)f.push(R(qa(b[h]),
|
||||||
b),a.quit(1,y)))}finally{}};a.run=a.run=La;a.exit=a.exit=gb;var ib=[];a.abort=a.abort=M;if(a.preInit)for("function"==typeof a.preInit&&(a.preInit=[a.preInit]);0<a.preInit.length;)a.preInit.pop()();var cb=!0;a.noInitialRun&&(cb=!1);La();v.prototype=Object.create(v.prototype);v.prototype.constructor=v;v.prototype.__class__=v;v.__cache__={};a.WrapperObject=v;a.getCache=E;a.wrapPointer=Y;a.castObject=function(a,c){return Y(a.ptr,c)};a.NULL=Y(0);a.destroy=function(a){if(!a.__destroy__)throw"Error: Cannot destroy object. (Did you create it yourself?)";
|
"i8",0)),c();f.push(0);f=R(f,"i32",0);try{var k=a._main(e,f,0);fb(k,!0)}catch(y){y instanceof ma||("SimulateInfiniteLoop"==y?a.noExitRuntime=!0:((b=y)&&"object"===typeof y&&y.stack&&(b=[y,y.stack]),a.printErr("exception thrown: "+b),a.quit(1,y)))}finally{}};a.run=a.run=Ka;a.exit=a.exit=fb;var hb=[];a.abort=a.abort=M;if(a.preInit)for("function"==typeof a.preInit&&(a.preInit=[a.preInit]);0<a.preInit.length;)a.preInit.pop()();var bb=!0;a.noInitialRun&&(bb=!1);Ka();v.prototype=Object.create(v.prototype);
|
||||||
a.__destroy__();delete E(a.__class__)[a.ptr]};a.compare=function(a,c){return a.ptr===c.ptr};a.getPointer=function(a){return a.ptr};a.getClass=function(a){return a.__class__};var k={buffer:0,size:0,pos:0,temps:[],needed:0,prepare:function(){if(k.needed){for(var b=0;b<k.temps.length;b++)a._free(k.temps[b]);k.temps.length=0;a._free(k.buffer);k.buffer=0;k.size+=k.needed;k.needed=0}k.buffer||(k.size+=128,k.buffer=a._malloc(k.size),f(k.buffer));k.pos=0},alloc:function(b,c){f(k.buffer);b=b.length*c.BYTES_PER_ELEMENT;
|
v.prototype.constructor=v;v.prototype.__class__=v;v.__cache__={};a.WrapperObject=v;a.getCache=E;a.wrapPointer=V;a.castObject=function(a,c){return V(a.ptr,c)};a.NULL=V(0);a.destroy=function(a){if(!a.__destroy__)throw"Error: Cannot destroy object. (Did you create it yourself?)";a.__destroy__();delete E(a.__class__)[a.ptr]};a.compare=function(a,c){return a.ptr===c.ptr};a.getPointer=function(a){return a.ptr};a.getClass=function(a){return a.__class__};var l={buffer:0,size:0,pos:0,temps:[],needed:0,prepare:function(){if(l.needed){for(var b=
|
||||||
b=b+7&-8;k.pos+b>=k.size?(f(0<b),k.needed+=b,c=a._malloc(b),k.temps.push(c)):(c=k.buffer+k.pos,k.pos+=b);return c},copy:function(a,c,e){switch(c.BYTES_PER_ELEMENT){case 2:e>>=1;break;case 4:e>>=2;break;case 8:e>>=3}for(var b=0;b<a.length;b++)c[e+b]=a[b]}};D.prototype=Object.create(v.prototype);D.prototype.constructor=D;D.prototype.__class__=D;D.__cache__={};a.Status=D;D.prototype.code=D.prototype.code=function(){return nd(this.ptr)};D.prototype.ok=D.prototype.ok=function(){return!!ac(this.ptr)};D.prototype.error_msg=
|
0;b<l.temps.length;b++)a._free(l.temps[b]);l.temps.length=0;a._free(l.buffer);l.buffer=0;l.size+=l.needed;l.needed=0}l.buffer||(l.size+=128,l.buffer=a._malloc(l.size),f(l.buffer));l.pos=0},alloc:function(b,c){f(l.buffer);b=b.length*c.BYTES_PER_ELEMENT;b=b+7&-8;l.pos+b>=l.size?(f(0<b),l.needed+=b,c=a._malloc(b),l.temps.push(c)):(c=l.buffer+l.pos,l.pos+=b);return c},copy:function(a,c,e){switch(c.BYTES_PER_ELEMENT){case 2:e>>=1;break;case 4:e>>=2;break;case 8:e>>=3}for(var b=0;b<a.length;b++)c[e+b]=
|
||||||
D.prototype.error_msg=function(){return t(ed(this.ptr))};D.prototype.__destroy__=D.prototype.__destroy__=function(){hd(this.ptr)};I.prototype=Object.create(v.prototype);I.prototype.constructor=I;I.prototype.__class__=I;I.__cache__={};a.PointCloud=I;I.prototype.num_attributes=I.prototype.num_attributes=function(){return tc(this.ptr)};I.prototype.num_points=I.prototype.num_points=function(){return Xc(this.ptr)};I.prototype.__destroy__=I.prototype.__destroy__=function(){Yc(this.ptr)};J.prototype=Object.create(v.prototype);
|
a[b]}};D.prototype=Object.create(v.prototype);D.prototype.constructor=D;D.prototype.__class__=D;D.__cache__={};a.Status=D;D.prototype.code=D.prototype.code=function(){return nd(this.ptr)};D.prototype.ok=D.prototype.ok=function(){return!!$b(this.ptr)};D.prototype.error_msg=D.prototype.error_msg=function(){return t(ed(this.ptr))};D.prototype.__destroy__=D.prototype.__destroy__=function(){hd(this.ptr)};I.prototype=Object.create(v.prototype);I.prototype.constructor=I;I.prototype.__class__=I;I.__cache__=
|
||||||
J.prototype.constructor=J;J.prototype.__class__=J;J.__cache__={};a.AttributeOctahedronTransform=J;J.prototype.InitFromAttribute=J.prototype.InitFromAttribute=function(a){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);return!!bd(b,a)};J.prototype.quantization_bits=J.prototype.quantization_bits=function(){return yc(this.ptr)};J.prototype.__destroy__=J.prototype.__destroy__=function(){zc(this.ptr)};p.prototype=Object.create(v.prototype);p.prototype.constructor=p;p.prototype.__class__=p;p.__cache__=
|
{};a.PointCloud=I;I.prototype.num_attributes=I.prototype.num_attributes=function(){return sc(this.ptr)};I.prototype.num_points=I.prototype.num_points=function(){return Xc(this.ptr)};I.prototype.__destroy__=I.prototype.__destroy__=function(){Uc(this.ptr)};J.prototype=Object.create(v.prototype);J.prototype.constructor=J;J.prototype.__class__=J;J.__cache__={};a.AttributeOctahedronTransform=J;J.prototype.InitFromAttribute=J.prototype.InitFromAttribute=function(a){var b=this.ptr;a&&"object"===typeof a&&
|
||||||
{};a.PointAttribute=p;p.prototype.size=p.prototype.size=function(){return Wb(this.ptr)};p.prototype.GetAttributeTransformData=p.prototype.GetAttributeTransformData=function(){return Y(cd(this.ptr),O)};p.prototype.attribute_type=p.prototype.attribute_type=function(){return Pc(this.ptr)};p.prototype.data_type=p.prototype.data_type=function(){return $c(this.ptr)};p.prototype.num_components=p.prototype.num_components=function(){return pc(this.ptr)};p.prototype.normalized=p.prototype.normalized=function(){return!!Tb(this.ptr)};
|
(a=a.ptr);return!!bd(b,a)};J.prototype.quantization_bits=J.prototype.quantization_bits=function(){return yc(this.ptr)};J.prototype.__destroy__=J.prototype.__destroy__=function(){zc(this.ptr)};p.prototype=Object.create(v.prototype);p.prototype.constructor=p;p.prototype.__class__=p;p.__cache__={};a.PointAttribute=p;p.prototype.size=p.prototype.size=function(){return Vb(this.ptr)};p.prototype.GetAttributeTransformData=p.prototype.GetAttributeTransformData=function(){return V(cd(this.ptr),O)};p.prototype.attribute_type=
|
||||||
p.prototype.byte_stride=p.prototype.byte_stride=function(){return hc(this.ptr)};p.prototype.byte_offset=p.prototype.byte_offset=function(){return dd(this.ptr)};p.prototype.unique_id=p.prototype.unique_id=function(){return Bc(this.ptr)};p.prototype.__destroy__=p.prototype.__destroy__=function(){ud(this.ptr)};O.prototype=Object.create(v.prototype);O.prototype.constructor=O;O.prototype.__class__=O;O.__cache__={};a.AttributeTransformData=O;O.prototype.transform_type=O.prototype.transform_type=function(){return md(this.ptr)};
|
p.prototype.attribute_type=function(){return Pc(this.ptr)};p.prototype.data_type=p.prototype.data_type=function(){return $c(this.ptr)};p.prototype.num_components=p.prototype.num_components=function(){return oc(this.ptr)};p.prototype.normalized=p.prototype.normalized=function(){return!!Sb(this.ptr)};p.prototype.byte_stride=p.prototype.byte_stride=function(){return gc(this.ptr)};p.prototype.byte_offset=p.prototype.byte_offset=function(){return dd(this.ptr)};p.prototype.unique_id=p.prototype.unique_id=
|
||||||
O.prototype.__destroy__=O.prototype.__destroy__=function(){oc(this.ptr)};B.prototype=Object.create(v.prototype);B.prototype.constructor=B;B.prototype.__class__=B;B.__cache__={};a.AttributeQuantizationTransform=B;B.prototype.InitFromAttribute=B.prototype.InitFromAttribute=function(a){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);return!!td(b,a)};B.prototype.quantization_bits=B.prototype.quantization_bits=function(){return Lc(this.ptr)};B.prototype.min_value=B.prototype.min_value=function(a){var b=
|
function(){return Bc(this.ptr)};p.prototype.__destroy__=p.prototype.__destroy__=function(){ud(this.ptr)};O.prototype=Object.create(v.prototype);O.prototype.constructor=O;O.prototype.__class__=O;O.__cache__={};a.AttributeTransformData=O;O.prototype.transform_type=O.prototype.transform_type=function(){return md(this.ptr)};O.prototype.__destroy__=O.prototype.__destroy__=function(){nc(this.ptr)};B.prototype=Object.create(v.prototype);B.prototype.constructor=B;B.prototype.__class__=B;B.__cache__={};a.AttributeQuantizationTransform=
|
||||||
this.ptr;a&&"object"===typeof a&&(a=a.ptr);return ic(b,a)};B.prototype.range=B.prototype.range=function(){return jd(this.ptr)};B.prototype.__destroy__=B.prototype.__destroy__=function(){qc(this.ptr)};q.prototype=Object.create(v.prototype);q.prototype.constructor=q;q.prototype.__class__=q;q.__cache__={};a.MetadataQuerier=q;q.prototype.HasIntEntry=q.prototype.HasIntEntry=function(a,c){var b=this.ptr;k.prepare();a&&"object"===typeof a&&(a=a.ptr);c=c&&"object"===typeof c?c.ptr:Z(c);return!!Dc(b,a,c)};
|
B;B.prototype.InitFromAttribute=B.prototype.InitFromAttribute=function(a){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);return!!td(b,a)};B.prototype.quantization_bits=B.prototype.quantization_bits=function(){return Lc(this.ptr)};B.prototype.min_value=B.prototype.min_value=function(a){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);return hc(b,a)};B.prototype.range=B.prototype.range=function(){return jd(this.ptr)};B.prototype.__destroy__=B.prototype.__destroy__=function(){pc(this.ptr)};q.prototype=
|
||||||
q.prototype.GetIntEntry=q.prototype.GetIntEntry=function(a,c){var b=this.ptr;k.prepare();a&&"object"===typeof a&&(a=a.ptr);c=c&&"object"===typeof c?c.ptr:Z(c);return kc(b,a,c)};q.prototype.HasDoubleEntry=q.prototype.HasDoubleEntry=function(a,c){var b=this.ptr;k.prepare();a&&"object"===typeof a&&(a=a.ptr);c=c&&"object"===typeof c?c.ptr:Z(c);return!!vc(b,a,c)};q.prototype.GetDoubleEntry=q.prototype.GetDoubleEntry=function(a,c){var b=this.ptr;k.prepare();a&&"object"===typeof a&&(a=a.ptr);c=c&&"object"===
|
Object.create(v.prototype);q.prototype.constructor=q;q.prototype.__class__=q;q.__cache__={};a.MetadataQuerier=q;q.prototype.HasIntEntry=q.prototype.HasIntEntry=function(a,c){var b=this.ptr;l.prepare();a&&"object"===typeof a&&(a=a.ptr);c=c&&"object"===typeof c?c.ptr:Z(c);return!!Dc(b,a,c)};q.prototype.GetIntEntry=q.prototype.GetIntEntry=function(a,c){var b=this.ptr;l.prepare();a&&"object"===typeof a&&(a=a.ptr);c=c&&"object"===typeof c?c.ptr:Z(c);return jc(b,a,c)};q.prototype.HasDoubleEntry=q.prototype.HasDoubleEntry=
|
||||||
typeof c?c.ptr:Z(c);return wc(b,a,c)};q.prototype.HasStringEntry=q.prototype.HasStringEntry=function(a,c){var b=this.ptr;k.prepare();a&&"object"===typeof a&&(a=a.ptr);c=c&&"object"===typeof c?c.ptr:Z(c);return!!nc(b,a,c)};q.prototype.GetStringEntry=q.prototype.GetStringEntry=function(a,c){var b=this.ptr;k.prepare();a&&"object"===typeof a&&(a=a.ptr);c=c&&"object"===typeof c?c.ptr:Z(c);return t(jc(b,a,c))};q.prototype.__destroy__=q.prototype.__destroy__=function(){Qc(this.ptr)};K.prototype=Object.create(v.prototype);
|
function(a,c){var b=this.ptr;l.prepare();a&&"object"===typeof a&&(a=a.ptr);c=c&&"object"===typeof c?c.ptr:Z(c);return!!vc(b,a,c)};q.prototype.GetDoubleEntry=q.prototype.GetDoubleEntry=function(a,c){var b=this.ptr;l.prepare();a&&"object"===typeof a&&(a=a.ptr);c=c&&"object"===typeof c?c.ptr:Z(c);return wc(b,a,c)};q.prototype.HasStringEntry=q.prototype.HasStringEntry=function(a,c){var b=this.ptr;l.prepare();a&&"object"===typeof a&&(a=a.ptr);c=c&&"object"===typeof c?c.ptr:Z(c);return!!mc(b,a,c)};q.prototype.GetStringEntry=
|
||||||
K.prototype.constructor=K;K.prototype.__class__=K;K.__cache__={};a.DracoFloat32Array=K;K.prototype.GetValue=K.prototype.GetValue=function(a){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);return qd(b,a)};K.prototype.size=K.prototype.size=function(){return ad(this.ptr)};K.prototype.__destroy__=K.prototype.__destroy__=function(){Wc(this.ptr)};V.prototype=Object.create(v.prototype);V.prototype.constructor=V;V.prototype.__class__=V;V.__cache__={};a.GeometryAttribute=V;V.prototype.__destroy__=V.prototype.__destroy__=
|
q.prototype.GetStringEntry=function(a,c){var b=this.ptr;l.prepare();a&&"object"===typeof a&&(a=a.ptr);c=c&&"object"===typeof c?c.ptr:Z(c);return t(ic(b,a,c))};q.prototype.__destroy__=q.prototype.__destroy__=function(){Qc(this.ptr)};K.prototype=Object.create(v.prototype);K.prototype.constructor=K;K.prototype.__class__=K;K.__cache__={};a.DracoFloat32Array=K;K.prototype.GetValue=K.prototype.GetValue=function(a){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);return qd(b,a)};K.prototype.size=K.prototype.size=
|
||||||
function(){gc(this.ptr)};P.prototype=Object.create(v.prototype);P.prototype.constructor=P;P.prototype.__class__=P;P.__cache__={};a.DecoderBuffer=P;P.prototype.Init=P.prototype.Init=function(a,c){var b=this.ptr;k.prepare();if("object"==typeof a&&"object"===typeof a){var e=k.alloc(a,N);k.copy(a,N,e);a=e}c&&"object"===typeof c&&(c=c.ptr);Vb(b,a,c)};P.prototype.__destroy__=P.prototype.__destroy__=function(){Sc(this.ptr)};l.prototype=Object.create(v.prototype);l.prototype.constructor=l;l.prototype.__class__=
|
function(){return ad(this.ptr)};K.prototype.__destroy__=K.prototype.__destroy__=function(){Wc(this.ptr)};W.prototype=Object.create(v.prototype);W.prototype.constructor=W;W.prototype.__class__=W;W.__cache__={};a.GeometryAttribute=W;W.prototype.__destroy__=W.prototype.__destroy__=function(){fc(this.ptr)};P.prototype=Object.create(v.prototype);P.prototype.constructor=P;P.prototype.__class__=P;P.__cache__={};a.DecoderBuffer=P;P.prototype.Init=P.prototype.Init=function(a,c){var b=this.ptr;l.prepare();
|
||||||
l;l.__cache__={};a.Decoder=l;l.prototype.GetEncodedGeometryType=l.prototype.GetEncodedGeometryType=function(a){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);return ec(b,a)};l.prototype.DecodeBufferToPointCloud=l.prototype.DecodeBufferToPointCloud=function(a,c){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);c&&"object"===typeof c&&(c=c.ptr);return Y(cc(b,a,c),D)};l.prototype.DecodeBufferToMesh=l.prototype.DecodeBufferToMesh=function(a,c){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);c&&"object"===
|
if("object"==typeof a&&"object"===typeof a){var e=l.alloc(a,N);l.copy(a,N,e);a=e}c&&"object"===typeof c&&(c=c.ptr);Ub(b,a,c)};P.prototype.__destroy__=P.prototype.__destroy__=function(){Sc(this.ptr)};m.prototype=Object.create(v.prototype);m.prototype.constructor=m;m.prototype.__class__=m;m.__cache__={};a.Decoder=m;m.prototype.GetEncodedGeometryType=m.prototype.GetEncodedGeometryType=function(a){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);return dc(b,a)};m.prototype.DecodeBufferToPointCloud=m.prototype.DecodeBufferToPointCloud=
|
||||||
typeof c&&(c=c.ptr);return Y(pd(b,a,c),D)};l.prototype.GetAttributeId=l.prototype.GetAttributeId=function(a,c){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);c&&"object"===typeof c&&(c=c.ptr);return kd(b,a,c)};l.prototype.GetAttributeIdByName=l.prototype.GetAttributeIdByName=function(a,c){var b=this.ptr;k.prepare();a&&"object"===typeof a&&(a=a.ptr);c=c&&"object"===typeof c?c.ptr:Z(c);return Zb(b,a,c)};l.prototype.GetAttributeIdByMetadataEntry=l.prototype.GetAttributeIdByMetadataEntry=function(a,
|
function(a,c){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);c&&"object"===typeof c&&(c=c.ptr);return V(bc(b,a,c),D)};m.prototype.DecodeBufferToMesh=m.prototype.DecodeBufferToMesh=function(a,c){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);c&&"object"===typeof c&&(c=c.ptr);return V(pd(b,a,c),D)};m.prototype.GetAttributeId=m.prototype.GetAttributeId=function(a,c){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);c&&"object"===typeof c&&(c=c.ptr);return kd(b,a,c)};m.prototype.GetAttributeIdByName=
|
||||||
c,e){var b=this.ptr;k.prepare();a&&"object"===typeof a&&(a=a.ptr);c=c&&"object"===typeof c?c.ptr:Z(c);e=e&&"object"===typeof e?e.ptr:Z(e);return uc(b,a,c,e)};l.prototype.GetAttribute=l.prototype.GetAttribute=function(a,c){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);c&&"object"===typeof c&&(c=c.ptr);return Y(Tc(b,a,c),p)};l.prototype.GetMetadata=l.prototype.GetMetadata=function(a){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);return Y(rd(b,a),Q)};l.prototype.GetAttributeMetadata=l.prototype.GetAttributeMetadata=
|
m.prototype.GetAttributeIdByName=function(a,c){var b=this.ptr;l.prepare();a&&"object"===typeof a&&(a=a.ptr);c=c&&"object"===typeof c?c.ptr:Z(c);return Yb(b,a,c)};m.prototype.GetAttributeIdByMetadataEntry=m.prototype.GetAttributeIdByMetadataEntry=function(a,c,e){var b=this.ptr;l.prepare();a&&"object"===typeof a&&(a=a.ptr);c=c&&"object"===typeof c?c.ptr:Z(c);e=e&&"object"===typeof e?e.ptr:Z(e);return uc(b,a,c,e)};m.prototype.GetAttribute=m.prototype.GetAttribute=function(a,c){var b=this.ptr;a&&"object"===
|
||||||
function(a,c){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);c&&"object"===typeof c&&(c=c.ptr);return Y(Ac(b,a,c),Q)};l.prototype.GetFaceFromMesh=l.prototype.GetFaceFromMesh=function(a,c,e){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);c&&"object"===typeof c&&(c=c.ptr);e&&"object"===typeof e&&(e=e.ptr);return!!Zc(b,a,c,e)};l.prototype.GetTriangleStripsFromMesh=l.prototype.GetTriangleStripsFromMesh=function(a,c){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);c&&"object"===typeof c&&(c=c.ptr);
|
typeof a&&(a=a.ptr);c&&"object"===typeof c&&(c=c.ptr);return V(Tc(b,a,c),p)};m.prototype.GetAttributeByUniqueId=m.prototype.GetAttributeByUniqueId=function(a,c){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);c&&"object"===typeof c&&(c=c.ptr);return V(tc(b,a,c),p)};m.prototype.GetMetadata=m.prototype.GetMetadata=function(a){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);return V(rd(b,a),Q)};m.prototype.GetAttributeMetadata=m.prototype.GetAttributeMetadata=function(a,c){var b=this.ptr;a&&"object"===
|
||||||
return Ec(b,a,c)};l.prototype.GetAttributeFloat=l.prototype.GetAttributeFloat=function(a,c,e){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);c&&"object"===typeof c&&(c=c.ptr);e&&"object"===typeof e&&(e=e.ptr);return!!Sb(b,a,c,e)};l.prototype.GetAttributeFloatForAllPoints=l.prototype.GetAttributeFloatForAllPoints=function(a,c,e){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);c&&"object"===typeof c&&(c=c.ptr);e&&"object"===typeof e&&(e=e.ptr);return!!Ub(b,a,c,e)};l.prototype.GetAttributeIntForAllPoints=
|
typeof a&&(a=a.ptr);c&&"object"===typeof c&&(c=c.ptr);return V(Ac(b,a,c),Q)};m.prototype.GetFaceFromMesh=m.prototype.GetFaceFromMesh=function(a,c,e){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);c&&"object"===typeof c&&(c=c.ptr);e&&"object"===typeof e&&(e=e.ptr);return!!Zc(b,a,c,e)};m.prototype.GetTriangleStripsFromMesh=m.prototype.GetTriangleStripsFromMesh=function(a,c){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);c&&"object"===typeof c&&(c=c.ptr);return Ec(b,a,c)};m.prototype.GetAttributeFloat=
|
||||||
l.prototype.GetAttributeIntForAllPoints=function(a,c,e){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);c&&"object"===typeof c&&(c=c.ptr);e&&"object"===typeof e&&(e=e.ptr);return!!Jc(b,a,c,e)};l.prototype.SkipAttributeTransform=l.prototype.SkipAttributeTransform=function(a){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);Hc(b,a)};l.prototype.__destroy__=l.prototype.__destroy__=function(){lc(this.ptr)};F.prototype=Object.create(v.prototype);F.prototype.constructor=F;F.prototype.__class__=F;F.__cache__=
|
m.prototype.GetAttributeFloat=function(a,c,e){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);c&&"object"===typeof c&&(c=c.ptr);e&&"object"===typeof e&&(e=e.ptr);return!!Rb(b,a,c,e)};m.prototype.GetAttributeFloatForAllPoints=m.prototype.GetAttributeFloatForAllPoints=function(a,c,e){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);c&&"object"===typeof c&&(c=c.ptr);e&&"object"===typeof e&&(e=e.ptr);return!!Tb(b,a,c,e)};m.prototype.GetAttributeIntForAllPoints=m.prototype.GetAttributeIntForAllPoints=
|
||||||
{};a.Mesh=F;F.prototype.num_faces=F.prototype.num_faces=function(){return bc(this.ptr)};F.prototype.num_attributes=F.prototype.num_attributes=function(){return xc(this.ptr)};F.prototype.num_points=F.prototype.num_points=function(){return sc(this.ptr)};F.prototype.__destroy__=F.prototype.__destroy__=function(){fd(this.ptr)};aa.prototype=Object.create(v.prototype);aa.prototype.constructor=aa;aa.prototype.__class__=aa;aa.__cache__={};a.VoidPtr=aa;aa.prototype.__destroy__=aa.prototype.__destroy__=function(){Oc(this.ptr)};
|
function(a,c,e){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);c&&"object"===typeof c&&(c=c.ptr);e&&"object"===typeof e&&(e=e.ptr);return!!Jc(b,a,c,e)};m.prototype.SkipAttributeTransform=m.prototype.SkipAttributeTransform=function(a){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);Hc(b,a)};m.prototype.__destroy__=m.prototype.__destroy__=function(){kc(this.ptr)};F.prototype=Object.create(v.prototype);F.prototype.constructor=F;F.prototype.__class__=F;F.__cache__={};a.Mesh=F;F.prototype.num_faces=
|
||||||
L.prototype=Object.create(v.prototype);L.prototype.constructor=L;L.prototype.__class__=L;L.__cache__={};a.DracoInt32Array=L;L.prototype.GetValue=L.prototype.GetValue=function(a){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);return Rc(b,a)};L.prototype.size=L.prototype.size=function(){return Gc(this.ptr)};L.prototype.__destroy__=L.prototype.__destroy__=function(){rc(this.ptr)};Q.prototype=Object.create(v.prototype);Q.prototype.constructor=Q;Q.prototype.__class__=Q;Q.__cache__={};a.Metadata=Q;Q.prototype.__destroy__=
|
F.prototype.num_faces=function(){return ac(this.ptr)};F.prototype.num_attributes=F.prototype.num_attributes=function(){return xc(this.ptr)};F.prototype.num_points=F.prototype.num_points=function(){return rc(this.ptr)};F.prototype.__destroy__=F.prototype.__destroy__=function(){fd(this.ptr)};aa.prototype=Object.create(v.prototype);aa.prototype.constructor=aa;aa.prototype.__class__=aa;aa.__cache__={};a.VoidPtr=aa;aa.prototype.__destroy__=aa.prototype.__destroy__=function(){Oc(this.ptr)};L.prototype=
|
||||||
Q.prototype.__destroy__=function(){gd(this.ptr)};(function(){function b(){a.OK=ld();a.ERROR=Kc();a.IO_ERROR=Cc();a.INVALID_PARAMETER=Mc();a.UNSUPPORTED_VERSION=vd();a.UNKNOWN_VERSION=Vc();a.INVALID_GEOMETRY_TYPE=fc();a.POINT_CLOUD=$b();a.TRIANGULAR_MESH=Uc();a.ATTRIBUTE_INVALID_TRANSFORM=id();a.ATTRIBUTE_NO_TRANSFORM=dc();a.ATTRIBUTE_QUANTIZATION_TRANSFORM=Ic();a.ATTRIBUTE_OCTAHEDRON_TRANSFORM=mc();a.INVALID=Yb();a.POSITION=Xb();a.NORMAL=sd();a.COLOR=Nc();a.TEX_COORD=Fc();a.GENERIC=od()}a.calledRun?
|
Object.create(v.prototype);L.prototype.constructor=L;L.prototype.__class__=L;L.__cache__={};a.DracoInt32Array=L;L.prototype.GetValue=L.prototype.GetValue=function(a){var b=this.ptr;a&&"object"===typeof a&&(a=a.ptr);return Rc(b,a)};L.prototype.size=L.prototype.size=function(){return Gc(this.ptr)};L.prototype.__destroy__=L.prototype.__destroy__=function(){qc(this.ptr)};Q.prototype=Object.create(v.prototype);Q.prototype.constructor=Q;Q.prototype.__class__=Q;Q.__cache__={};a.Metadata=Q;Q.prototype.__destroy__=
|
||||||
b():bb.unshift(b)})();if("function"===typeof a.onModuleParsed)a.onModuleParsed();return e};"object"===typeof module&&module.exports&&(module.exports=DracoDecoderModule);
|
Q.prototype.__destroy__=function(){gd(this.ptr)};(function(){function b(){a.OK=ld();a.ERROR=Kc();a.IO_ERROR=Cc();a.INVALID_PARAMETER=Mc();a.UNSUPPORTED_VERSION=vd();a.UNKNOWN_VERSION=Vc();a.INVALID_GEOMETRY_TYPE=ec();a.POINT_CLOUD=Zb();a.TRIANGULAR_MESH=Yc();a.ATTRIBUTE_INVALID_TRANSFORM=id();a.ATTRIBUTE_NO_TRANSFORM=cc();a.ATTRIBUTE_QUANTIZATION_TRANSFORM=Ic();a.ATTRIBUTE_OCTAHEDRON_TRANSFORM=lc();a.INVALID=Xb();a.POSITION=Wb();a.NORMAL=sd();a.COLOR=Nc();a.TEX_COORD=Fc();a.GENERIC=od()}a.calledRun?
|
||||||
|
b():ab.unshift(b)})();if("function"===typeof a.onModuleParsed)a.onModuleParsed();return e};"object"===typeof module&&module.exports&&(module.exports=DracoDecoderModule);
|
||||||
|
@ -14,9 +14,10 @@
|
|||||||
//
|
//
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// If |dracoDecoderType|.type is set to "js", then DRACOLoader will load the
|
// |dracoPath| sets the path for the Draco decoder source files. The default
|
||||||
// Draco JavaScript decoder.
|
// path is "./". If |dracoDecoderType|.type is set to "js", then DRACOLoader
|
||||||
THREE.DRACOLoader = function(manager, dracoDecoderType) {
|
// will load the Draco JavaScript decoder.
|
||||||
|
THREE.DRACOLoader = function(dracoPath, dracoDecoderType, manager) {
|
||||||
this.timeLoaded = 0;
|
this.timeLoaded = 0;
|
||||||
this.manager = (manager !== undefined) ? manager :
|
this.manager = (manager !== undefined) ? manager :
|
||||||
THREE.DefaultLoadingManager;
|
THREE.DefaultLoadingManager;
|
||||||
@ -26,6 +27,7 @@ THREE.DRACOLoader = function(manager, dracoDecoderType) {
|
|||||||
this.dracoDecoderType =
|
this.dracoDecoderType =
|
||||||
(dracoDecoderType !== undefined) ? dracoDecoderType : {};
|
(dracoDecoderType !== undefined) ? dracoDecoderType : {};
|
||||||
this.drawMode = THREE.TrianglesDrawMode;
|
this.drawMode = THREE.TrianglesDrawMode;
|
||||||
|
this.dracoSrcPath = (dracoPath !== undefined) ? dracoPath : './';
|
||||||
THREE.DRACOLoader.loadDracoDecoder(this);
|
THREE.DRACOLoader.loadDracoDecoder(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -399,9 +401,10 @@ THREE.DRACOLoader.loadJavaScriptFile = function(path, onLoadFunc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
THREE.DRACOLoader.loadWebAssemblyDecoder = function(dracoDecoder) {
|
THREE.DRACOLoader.loadWebAssemblyDecoder = function(dracoDecoder) {
|
||||||
dracoDecoder.dracoDecoderType['wasmBinaryFile'] = '../draco_decoder.wasm';
|
dracoDecoder.dracoDecoderType['wasmBinaryFile'] =
|
||||||
|
dracoDecoder.dracoSrcPath + 'draco_decoder.wasm';
|
||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
xhr.open('GET', '../draco_decoder.wasm', true);
|
xhr.open('GET', dracoDecoder.dracoSrcPath + 'draco_decoder.wasm', true);
|
||||||
xhr.responseType = 'arraybuffer';
|
xhr.responseType = 'arraybuffer';
|
||||||
xhr.onload = function() {
|
xhr.onload = function() {
|
||||||
// draco_wasm_wrapper.js must be loaded before DracoDecoderModule is
|
// draco_wasm_wrapper.js must be loaded before DracoDecoderModule is
|
||||||
@ -421,10 +424,11 @@ THREE.DRACOLoader.loadDracoDecoder = function(dracoDecoder) {
|
|||||||
if (typeof WebAssembly !== 'object' ||
|
if (typeof WebAssembly !== 'object' ||
|
||||||
dracoDecoder.dracoDecoderType.type === 'js') {
|
dracoDecoder.dracoDecoderType.type === 'js') {
|
||||||
// No WebAssembly support
|
// No WebAssembly support
|
||||||
THREE.DRACOLoader.loadJavaScriptFile('../draco_decoder.js',
|
THREE.DRACOLoader.loadJavaScriptFile(dracoDecoder.dracoSrcPath +
|
||||||
null, dracoDecoder);
|
'draco_decoder.js', null, dracoDecoder);
|
||||||
} else {
|
} else {
|
||||||
THREE.DRACOLoader.loadJavaScriptFile('../draco_wasm_wrapper.js',
|
THREE.DRACOLoader.loadJavaScriptFile(dracoDecoder.dracoSrcPath +
|
||||||
|
'draco_wasm_wrapper.js',
|
||||||
function (dracoDecoder) {
|
function (dracoDecoder) {
|
||||||
THREE.DRACOLoader.loadWebAssemblyDecoder(dracoDecoder);
|
THREE.DRACOLoader.loadWebAssemblyDecoder(dracoDecoder);
|
||||||
}, dracoDecoder);
|
}, dracoDecoder);
|
@ -29,7 +29,7 @@
|
|||||||
<pre id="fileDisplayArea"><pre>
|
<pre id="fileDisplayArea"><pre>
|
||||||
</div>
|
</div>
|
||||||
<script src="https://cdn.rawgit.com/mrdoob/three.js/dev/build/three.min.js"></script>
|
<script src="https://cdn.rawgit.com/mrdoob/three.js/dev/build/three.min.js"></script>
|
||||||
<script src="../DRACOLoader.js"></script>
|
<script src="DRACOLoader.js"></script>
|
||||||
<script src="geometry_helper.js"></script>
|
<script src="geometry_helper.js"></script>
|
||||||
<script>
|
<script>
|
||||||
'use strict';
|
'use strict';
|
||||||
@ -41,7 +41,7 @@
|
|||||||
createDracoDecoder();
|
createDracoDecoder();
|
||||||
|
|
||||||
function createDracoDecoder() {
|
function createDracoDecoder() {
|
||||||
dracoLoader = new THREE.DRACOLoader();
|
dracoLoader = new THREE.DRACOLoader('../');
|
||||||
}
|
}
|
||||||
|
|
||||||
function switchDecoder() {
|
function switchDecoder() {
|
||||||
@ -53,7 +53,7 @@
|
|||||||
dracoDecoderType.type = "wasm";
|
dracoDecoderType.type = "wasm";
|
||||||
showDecoder.innerText = "Now using WebAssembly Decoder.";
|
showDecoder.innerText = "Now using WebAssembly Decoder.";
|
||||||
}
|
}
|
||||||
dracoLoader = new THREE.DRACOLoader(undefined, dracoDecoderType);
|
dracoLoader = new THREE.DRACOLoader('../', dracoDecoderType);
|
||||||
}
|
}
|
||||||
|
|
||||||
var camera, cameraTarget, scene, renderer;
|
var camera, cameraTarget, scene, renderer;
|
||||||
|
@ -5,23 +5,17 @@
|
|||||||
|
|
||||||
News
|
News
|
||||||
=======
|
=======
|
||||||
### Version 1.0.0 release
|
### Version 1.1.0 release
|
||||||
The latest version of Draco brings many new enhancements to improve the
|
The latest version of Draco brings a number of new compression enhancements for
|
||||||
development experience:
|
even smaller models:
|
||||||
* Stable API release
|
* Improved compression
|
||||||
* Support for npm Javascript package management
|
* Up to 40% better compression of normals
|
||||||
* Javascript based encoder
|
* Up to 5% better compression for models with multiple attributes
|
||||||
* Generalized metadata for meshes and point clouds
|
* Faster decode speeds
|
||||||
* Now supporting material properties included along with encoded file
|
* 30% faster decoding for models with multiple attributes for lower compression levels 4 and below
|
||||||
* Improved compression rates:
|
* Note: Decreases compression by 10%.
|
||||||
* 15% better compression on smaller models
|
* Encoding of metadata to .obj (e.g. Draco can preserve material or sub-object names)
|
||||||
* 40% better compression of normals
|
* Security fixes
|
||||||
* Performance improvements (~10% faster encoding, decoding)
|
|
||||||
* Reduced GPU memory usage:
|
|
||||||
* Option to store decoded quantized attributes
|
|
||||||
* Support for triangle strip connectivity on decoded meshes
|
|
||||||
* iOS 9 Javascript decoder
|
|
||||||
* Bitstream specification now available
|
|
||||||
|
|
||||||
Description
|
Description
|
||||||
===========
|
===========
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "draco3d",
|
"name": "draco3d",
|
||||||
"version": "1.0.2",
|
"version": "1.1.0",
|
||||||
"description": "Draco is a library for compressing and decompressing 3D geometric meshes and point clouds. It is intended to improve the storage and transmission of 3D graphics.",
|
"description": "Draco is a library for compressing and decompressing 3D geometric meshes and point clouds. It is intended to improve the storage and transmission of 3D graphics.",
|
||||||
"main": "draco3d.js",
|
"main": "draco3d.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -47,13 +47,13 @@ class GeometryAttribute {
|
|||||||
NORMAL,
|
NORMAL,
|
||||||
COLOR,
|
COLOR,
|
||||||
TEX_COORD,
|
TEX_COORD,
|
||||||
// Total number of different attribute types.
|
|
||||||
// Always keep behind all named attributes.
|
|
||||||
NAMED_ATTRIBUTES_COUNT,
|
|
||||||
// A special id used to mark attributes that are not assigned to any known
|
// A special id used to mark attributes that are not assigned to any known
|
||||||
// predefined use case. Such attributes are often used for a shader specific
|
// predefined use case. Such attributes are often used for a shader specific
|
||||||
// data.
|
// data.
|
||||||
GENERIC = NAMED_ATTRIBUTES_COUNT
|
GENERIC,
|
||||||
|
// Total number of different attribute types.
|
||||||
|
// Always keep behind all named attributes.
|
||||||
|
NAMED_ATTRIBUTES_COUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
GeometryAttribute();
|
GeometryAttribute();
|
||||||
|
@ -83,7 +83,7 @@ bool AttributesDecoder::DecodeAttributesDecoderData(DecoderBuffer *in_buffer) {
|
|||||||
// Update the inverse map.
|
// Update the inverse map.
|
||||||
if (att_id >= static_cast<int32_t>(point_attribute_to_local_id_map_.size()))
|
if (att_id >= static_cast<int32_t>(point_attribute_to_local_id_map_.size()))
|
||||||
point_attribute_to_local_id_map_.resize(att_id + 1, -1);
|
point_attribute_to_local_id_map_.resize(att_id + 1, -1);
|
||||||
point_attribute_to_local_id_map_[att_id] = point_attribute_ids_.size() - 1;
|
point_attribute_to_local_id_map_[att_id] = i;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -101,8 +101,6 @@ bool MeshPredictionSchemeGeometricNormalDecoder<
|
|||||||
// Expecting in_data in octahedral coordinates, i.e., portable attribute.
|
// Expecting in_data in octahedral coordinates, i.e., portable attribute.
|
||||||
DCHECK_EQ(num_components, 2);
|
DCHECK_EQ(num_components, 2);
|
||||||
|
|
||||||
flip_normal_bit_decoder_.EndDecoding();
|
|
||||||
|
|
||||||
const int corner_map_size = this->mesh_data().data_to_corner_map()->size();
|
const int corner_map_size = this->mesh_data().data_to_corner_map()->size();
|
||||||
|
|
||||||
VectorD<int32_t, 3> pred_normal_3d;
|
VectorD<int32_t, 3> pred_normal_3d;
|
||||||
@ -126,6 +124,7 @@ bool MeshPredictionSchemeGeometricNormalDecoder<
|
|||||||
this->transform().ComputeOriginalValue(
|
this->transform().ComputeOriginalValue(
|
||||||
pred_normal_oct, in_corr + data_offset, out_data + data_offset);
|
pred_normal_oct, in_corr + data_offset, out_data + data_offset);
|
||||||
}
|
}
|
||||||
|
flip_normal_bit_decoder_.EndDecoding();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +138,9 @@ bool MeshPredictionSchemeGeometricNormalDecoder<
|
|||||||
|
|
||||||
uint8_t prediction_mode;
|
uint8_t prediction_mode;
|
||||||
buffer->Decode(&prediction_mode);
|
buffer->Decode(&prediction_mode);
|
||||||
if (prediction_mode)
|
|
||||||
|
if (!predictor_.SetNormalPredictionMode(
|
||||||
|
NormalPredictionMode(prediction_mode)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Init normal flips.
|
// Init normal flips.
|
||||||
|
@ -163,7 +163,7 @@ bool MeshPredictionSchemeGeometricNormalEncoder<
|
|||||||
if (!this->transform().EncodeTransformData(buffer))
|
if (!this->transform().EncodeTransformData(buffer))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const uint8_t prediction_mode = 0;
|
const uint8_t prediction_mode = predictor_.GetNormalPredictionMode();
|
||||||
if (!buffer->Encode(prediction_mode))
|
if (!buffer->Encode(prediction_mode))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -31,12 +31,14 @@ class MeshPredictionSchemeGeometricNormalPredictorArea
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
MeshPredictionSchemeGeometricNormalPredictorArea(const MeshDataT &md)
|
MeshPredictionSchemeGeometricNormalPredictorArea(const MeshDataT &md)
|
||||||
: Base(md){};
|
: Base(md) {
|
||||||
|
this->SetNormalPredictionMode(TRIANGLE_AREA);
|
||||||
|
};
|
||||||
virtual ~MeshPredictionSchemeGeometricNormalPredictorArea() {}
|
virtual ~MeshPredictionSchemeGeometricNormalPredictorArea() {}
|
||||||
|
|
||||||
// Computes predicted octahedral coordinates on a given corner.
|
// Computes predicted octahedral coordinates on a given corner.
|
||||||
virtual void ComputePredictedValue(CornerIndex corner_id,
|
void ComputePredictedValue(CornerIndex corner_id,
|
||||||
DataTypeT *prediction) override {
|
DataTypeT *prediction) override {
|
||||||
DCHECK(this->IsInitialized());
|
DCHECK(this->IsInitialized());
|
||||||
typedef typename MeshDataT::CornerTable CornerTable;
|
typedef typename MeshDataT::CornerTable CornerTable;
|
||||||
const CornerTable *const corner_table = this->mesh_data_.corner_table();
|
const CornerTable *const corner_table = this->mesh_data_.corner_table();
|
||||||
@ -48,36 +50,59 @@ class MeshPredictionSchemeGeometricNormalPredictorArea
|
|||||||
// Computing normals for triangles and adding them up.
|
// Computing normals for triangles and adding them up.
|
||||||
|
|
||||||
VectorD<int64_t, 3> normal;
|
VectorD<int64_t, 3> normal;
|
||||||
|
CornerIndex c_next, c_prev;
|
||||||
while (!cit.End()) {
|
while (!cit.End()) {
|
||||||
// Getting corners.
|
// Getting corners.
|
||||||
const CornerIndex c_next = corner_table->Next(corner_id);
|
if (this->normal_prediction_mode_ == ONE_TRIANGLE) {
|
||||||
const CornerIndex c_prev = corner_table->Previous(corner_id);
|
c_next = corner_table->Next(corner_id);
|
||||||
// Getting positions for next and previous.
|
c_prev = corner_table->Previous(corner_id);
|
||||||
const auto pos_next = this->GetPositionForCorner(c_next);
|
} else {
|
||||||
const auto pos_prev = this->GetPositionForCorner(c_prev);
|
c_next = corner_table->Next(cit.Corner());
|
||||||
|
c_prev = corner_table->Previous(cit.Corner());
|
||||||
|
}
|
||||||
|
const VectorD<int64_t, 3> pos_next = this->GetPositionForCorner(c_next);
|
||||||
|
const VectorD<int64_t, 3> pos_prev = this->GetPositionForCorner(c_prev);
|
||||||
|
|
||||||
// Computing delta vectors to next and prev.
|
// Computing delta vectors to next and prev.
|
||||||
const auto delta_next = pos_next - pos_cent;
|
const VectorD<int64_t, 3> delta_next = pos_next - pos_cent;
|
||||||
const auto delta_prev = pos_prev - pos_cent;
|
const VectorD<int64_t, 3> delta_prev = pos_prev - pos_cent;
|
||||||
|
|
||||||
// Computing cross product.
|
// Computing cross product.
|
||||||
const auto cross = CrossProduct(delta_next, delta_prev);
|
const VectorD<int64_t, 3> cross = CrossProduct(delta_next, delta_prev);
|
||||||
normal = normal + cross;
|
normal = normal + cross;
|
||||||
cit.Next();
|
cit.Next();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to int32_t, make sure entries are not too large.
|
// Convert to int32_t, make sure entries are not too large.
|
||||||
const int32_t abs_sum = normal.AbsSum();
|
|
||||||
constexpr int64_t upper_bound = 1 << 29;
|
constexpr int64_t upper_bound = 1 << 29;
|
||||||
if (abs_sum > upper_bound) {
|
if (this->normal_prediction_mode_ == ONE_TRIANGLE) {
|
||||||
const int64_t quotient = abs_sum / upper_bound;
|
const int32_t abs_sum = normal.AbsSum();
|
||||||
normal = normal / quotient;
|
if (abs_sum > upper_bound) {
|
||||||
|
const int64_t quotient = abs_sum / upper_bound;
|
||||||
|
normal = normal / quotient;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const int64_t abs_sum = normal.AbsSum();
|
||||||
|
if (abs_sum > upper_bound) {
|
||||||
|
const int64_t quotient = abs_sum / upper_bound;
|
||||||
|
normal = normal / quotient;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DCHECK_LE(normal.AbsSum(), upper_bound);
|
DCHECK_LE(normal.AbsSum(), upper_bound);
|
||||||
prediction[0] = static_cast<int32_t>(normal[0]);
|
prediction[0] = static_cast<int32_t>(normal[0]);
|
||||||
prediction[1] = static_cast<int32_t>(normal[1]);
|
prediction[1] = static_cast<int32_t>(normal[1]);
|
||||||
prediction[2] = static_cast<int32_t>(normal[2]);
|
prediction[2] = static_cast<int32_t>(normal[2]);
|
||||||
}
|
}
|
||||||
|
bool SetNormalPredictionMode(NormalPredictionMode mode) override {
|
||||||
|
if (mode == ONE_TRIANGLE) {
|
||||||
|
this->normal_prediction_mode_ = mode;
|
||||||
|
return true;
|
||||||
|
} else if (mode == TRIANGLE_AREA) {
|
||||||
|
this->normal_prediction_mode_ = mode;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace draco
|
} // namespace draco
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "draco/attributes/point_attribute.h"
|
#include "draco/attributes/point_attribute.h"
|
||||||
#include "draco/compression/attributes/normal_compression_utils.h"
|
#include "draco/compression/attributes/normal_compression_utils.h"
|
||||||
|
#include "draco/compression/config/compression_shared.h"
|
||||||
#include "draco/core/math_utils.h"
|
#include "draco/core/math_utils.h"
|
||||||
#include "draco/core/vector_d.h"
|
#include "draco/core/vector_d.h"
|
||||||
#include "draco/mesh/corner_table.h"
|
#include "draco/mesh/corner_table.h"
|
||||||
@ -51,6 +52,11 @@ class MeshPredictionSchemeGeometricNormalPredictorBase {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool SetNormalPredictionMode(NormalPredictionMode mode) = 0;
|
||||||
|
virtual NormalPredictionMode GetNormalPredictionMode() const {
|
||||||
|
return normal_prediction_mode_;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
VectorD<int64_t, 3> GetPositionForDataId(int data_id) const {
|
VectorD<int64_t, 3> GetPositionForDataId(int data_id) const {
|
||||||
DCHECK(this->IsInitialized());
|
DCHECK(this->IsInitialized());
|
||||||
@ -80,6 +86,7 @@ class MeshPredictionSchemeGeometricNormalPredictorBase {
|
|||||||
const PointAttribute *pos_attribute_;
|
const PointAttribute *pos_attribute_;
|
||||||
const PointIndex *entry_to_point_id_map_;
|
const PointIndex *entry_to_point_id_map_;
|
||||||
MeshDataT mesh_data_;
|
MeshDataT mesh_data_;
|
||||||
|
NormalPredictionMode normal_prediction_mode_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace draco
|
} // namespace draco
|
||||||
|
@ -268,8 +268,16 @@ void MeshPredictionSchemeTexCoordsDecoder<DataTypeT, TransformT, MeshDataT>::
|
|||||||
|
|
||||||
if (std::is_integral<DataTypeT>::value) {
|
if (std::is_integral<DataTypeT>::value) {
|
||||||
// Round the predicted value for integer types.
|
// Round the predicted value for integer types.
|
||||||
predicted_value_[0] = static_cast<int>(floor(predicted_uv[0] + 0.5));
|
if (std::isnan(predicted_uv[0])) {
|
||||||
predicted_value_[1] = static_cast<int>(floor(predicted_uv[1] + 0.5));
|
predicted_value_[0] = INT_MIN;
|
||||||
|
} else {
|
||||||
|
predicted_value_[0] = static_cast<int>(floor(predicted_uv[0] + 0.5));
|
||||||
|
}
|
||||||
|
if (std::isnan(predicted_uv[1])) {
|
||||||
|
predicted_value_[1] = INT_MIN;
|
||||||
|
} else {
|
||||||
|
predicted_value_[1] = static_cast<int>(floor(predicted_uv[1] + 0.5));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
predicted_value_[0] = static_cast<int>(predicted_uv[0]);
|
predicted_value_[0] = static_cast<int>(predicted_uv[0]);
|
||||||
predicted_value_[1] = static_cast<int>(predicted_uv[1]);
|
predicted_value_[1] = static_cast<int>(predicted_uv[1]);
|
||||||
|
@ -103,10 +103,17 @@ bool SequentialIntegerAttributeDecoder::DecodeIntegerValues(
|
|||||||
if (!in_buffer->Decode(&num_bytes))
|
if (!in_buffer->Decode(&num_bytes))
|
||||||
return false;
|
return false;
|
||||||
if (num_bytes == DataTypeLength(DT_INT32)) {
|
if (num_bytes == DataTypeLength(DT_INT32)) {
|
||||||
|
if (portable_attribute()->buffer()->data_size() <
|
||||||
|
sizeof(int32_t) * num_values)
|
||||||
|
return false;
|
||||||
if (!in_buffer->Decode(portable_attribute_data,
|
if (!in_buffer->Decode(portable_attribute_data,
|
||||||
sizeof(int32_t) * num_values))
|
sizeof(int32_t) * num_values))
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
if (portable_attribute()->buffer()->data_size() < num_bytes * num_values)
|
||||||
|
return false;
|
||||||
|
if (in_buffer->remaining_size() < num_bytes * num_values)
|
||||||
|
return false;
|
||||||
for (uint32_t i = 0; i < num_values; ++i) {
|
for (uint32_t i = 0; i < num_values; ++i) {
|
||||||
in_buffer->Decode(portable_attribute_data + i, num_bytes);
|
in_buffer->Decode(portable_attribute_data + i, num_bytes);
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ namespace draco {
|
|||||||
|
|
||||||
// Latest Draco bit-stream version.
|
// Latest Draco bit-stream version.
|
||||||
static constexpr uint8_t kDracoBitstreamVersionMajor = 2;
|
static constexpr uint8_t kDracoBitstreamVersionMajor = 2;
|
||||||
static constexpr uint8_t kDracoBitstreamVersionMinor = 0;
|
static constexpr uint8_t kDracoBitstreamVersionMinor = 1;
|
||||||
|
|
||||||
// Macro that converts the Draco bit-stream into one uint16_t number.
|
// Macro that converts the Draco bit-stream into one uint16_t number.
|
||||||
// Useful mostly when checking version numbers.
|
// Useful mostly when checking version numbers.
|
||||||
@ -120,6 +120,11 @@ struct DracoHeader {
|
|||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum NormalPredictionMode {
|
||||||
|
ONE_TRIANGLE = 0, // To be deprecated.
|
||||||
|
TRIANGLE_AREA = 1,
|
||||||
|
};
|
||||||
|
|
||||||
// Mask for setting and getting the bit for metadata in |flags| of header.
|
// Mask for setting and getting the bit for metadata in |flags| of header.
|
||||||
#define METADATA_FLAG_MASK 0x8000
|
#define METADATA_FLAG_MASK 0x8000
|
||||||
|
|
||||||
|
@ -68,6 +68,8 @@ class DracoOptions {
|
|||||||
bool default_val) const;
|
bool default_val) const;
|
||||||
void SetAttributeBool(const AttributeKey &att_key, const std::string &name,
|
void SetAttributeBool(const AttributeKey &att_key, const std::string &name,
|
||||||
bool val);
|
bool val);
|
||||||
|
bool IsAttributeOptionSet(const AttributeKey &att_key,
|
||||||
|
const std::string &name) const;
|
||||||
|
|
||||||
// Gets/sets a global option that is not specific to any attribute.
|
// Gets/sets a global option that is not specific to any attribute.
|
||||||
int GetGlobalInt(const std::string &name, int default_val) const {
|
int GetGlobalInt(const std::string &name, int default_val) const {
|
||||||
@ -82,6 +84,9 @@ class DracoOptions {
|
|||||||
void SetGlobalBool(const std::string &name, bool val) {
|
void SetGlobalBool(const std::string &name, bool val) {
|
||||||
global_options_.SetBool(name, val);
|
global_options_.SetBool(name, val);
|
||||||
}
|
}
|
||||||
|
bool IsGlobalOptionSet(const std::string &name) const {
|
||||||
|
return global_options_.IsOptionSet(name);
|
||||||
|
}
|
||||||
|
|
||||||
// Sets or replaces attribute options with the provided |options|.
|
// Sets or replaces attribute options with the provided |options|.
|
||||||
void SetAttributeOptions(const AttributeKey &att_key, const Options &options);
|
void SetAttributeOptions(const AttributeKey &att_key, const Options &options);
|
||||||
@ -156,6 +161,15 @@ void DracoOptions<AttributeKeyT>::SetAttributeBool(const AttributeKeyT &att_key,
|
|||||||
GetAttributeOptions(att_key)->SetBool(name, val);
|
GetAttributeOptions(att_key)->SetBool(name, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename AttributeKeyT>
|
||||||
|
bool DracoOptions<AttributeKeyT>::IsAttributeOptionSet(
|
||||||
|
const AttributeKey &att_key, const std::string &name) const {
|
||||||
|
const Options *const att_options = FindAttributeOptions(att_key);
|
||||||
|
if (att_options)
|
||||||
|
return att_options->IsOptionSet(name);
|
||||||
|
return global_options_.IsOptionSet(name);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename AttributeKeyT>
|
template <typename AttributeKeyT>
|
||||||
void DracoOptions<AttributeKeyT>::SetAttributeOptions(
|
void DracoOptions<AttributeKeyT>::SetAttributeOptions(
|
||||||
const AttributeKey &att_key, const Options &options) {
|
const AttributeKey &att_key, const Options &options) {
|
||||||
|
@ -43,7 +43,6 @@ namespace draco {
|
|||||||
template <class TraversalDecoder>
|
template <class TraversalDecoder>
|
||||||
MeshEdgeBreakerDecoderImpl<TraversalDecoder>::MeshEdgeBreakerDecoderImpl()
|
MeshEdgeBreakerDecoderImpl<TraversalDecoder>::MeshEdgeBreakerDecoderImpl()
|
||||||
: decoder_(nullptr),
|
: decoder_(nullptr),
|
||||||
num_processed_hole_events_(0),
|
|
||||||
last_symbol_id_(-1),
|
last_symbol_id_(-1),
|
||||||
last_vert_id_(-1),
|
last_vert_id_(-1),
|
||||||
last_face_id_(-1),
|
last_face_id_(-1),
|
||||||
@ -264,7 +263,6 @@ bool MeshEdgeBreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity() {
|
|||||||
init_face_configurations_.clear();
|
init_face_configurations_.clear();
|
||||||
init_corners_.clear();
|
init_corners_.clear();
|
||||||
|
|
||||||
num_processed_hole_events_ = 0;
|
|
||||||
last_symbol_id_ = -1;
|
last_symbol_id_ = -1;
|
||||||
|
|
||||||
last_face_id_ = -1;
|
last_face_id_ = -1;
|
||||||
@ -352,9 +350,16 @@ bool MeshEdgeBreakerDecoderImpl<TraversalDecoder>::DecodeConnectivity() {
|
|||||||
|
|
||||||
// Decode connectivity of non-position attributes.
|
// Decode connectivity of non-position attributes.
|
||||||
if (attribute_data_.size() > 0) {
|
if (attribute_data_.size() > 0) {
|
||||||
for (CornerIndex ci(0); ci < corner_table_->num_corners(); ci += 3) {
|
if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 1)) {
|
||||||
if (!DecodeAttributeConnectivitiesOnFace(ci))
|
for (CornerIndex ci(0); ci < corner_table_->num_corners(); ci += 3) {
|
||||||
return false;
|
if (!DecodeAttributeConnectivitiesOnFaceLegacy(ci))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (CornerIndex ci(0); ci < corner_table_->num_corners(); ci += 3) {
|
||||||
|
if (!DecodeAttributeConnectivitiesOnFace(ci))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
traversal_decoder_.Done();
|
traversal_decoder_.Done();
|
||||||
@ -761,11 +766,11 @@ MeshEdgeBreakerDecoderImpl<TraversalDecoder>::DecodeHoleAndTopologySplitEvents(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint32_t num_hole_events;
|
uint32_t num_hole_events = 0;
|
||||||
if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
|
if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
|
||||||
if (!decoder_buffer->Decode(&num_hole_events))
|
if (!decoder_buffer->Decode(&num_hole_events))
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 1)) {
|
||||||
if (!DecodeVarint(&num_hole_events, decoder_buffer))
|
if (!DecodeVarint(&num_hole_events, decoder_buffer))
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -794,8 +799,8 @@ MeshEdgeBreakerDecoderImpl<TraversalDecoder>::DecodeHoleAndTopologySplitEvents(
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class TraversalDecoder>
|
template <class TraversalDecoder>
|
||||||
bool MeshEdgeBreakerDecoderImpl<
|
bool MeshEdgeBreakerDecoderImpl<TraversalDecoder>::
|
||||||
TraversalDecoder>::DecodeAttributeConnectivitiesOnFace(CornerIndex corner) {
|
DecodeAttributeConnectivitiesOnFaceLegacy(CornerIndex corner) {
|
||||||
// Three corners of the face.
|
// Three corners of the face.
|
||||||
const CornerIndex corners[3] = {corner, corner_table_->Next(corner),
|
const CornerIndex corners[3] = {corner, corner_table_->Next(corner),
|
||||||
corner_table_->Previous(corner)};
|
corner_table_->Previous(corner)};
|
||||||
@ -820,6 +825,38 @@ bool MeshEdgeBreakerDecoderImpl<
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class TraversalDecoder>
|
||||||
|
bool MeshEdgeBreakerDecoderImpl<
|
||||||
|
TraversalDecoder>::DecodeAttributeConnectivitiesOnFace(CornerIndex corner) {
|
||||||
|
// Three corners of the face.
|
||||||
|
const CornerIndex corners[3] = {corner, corner_table_->Next(corner),
|
||||||
|
corner_table_->Previous(corner)};
|
||||||
|
|
||||||
|
const FaceIndex src_face_id = corner_table_->Face(corner);
|
||||||
|
for (int c = 0; c < 3; ++c) {
|
||||||
|
const CornerIndex opp_corner = corner_table_->Opposite(corners[c]);
|
||||||
|
if (opp_corner < 0) {
|
||||||
|
// Don't decode attribute seams on boundary edges (every boundary edge
|
||||||
|
// is automatically an attribute seam).
|
||||||
|
for (uint32_t i = 0; i < attribute_data_.size(); ++i) {
|
||||||
|
attribute_data_[i].attribute_seam_corners.push_back(corners[c].value());
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const FaceIndex opp_face_id = corner_table_->Face(opp_corner);
|
||||||
|
// Don't decode edges when the opposite face has been already processed.
|
||||||
|
if (opp_face_id < src_face_id)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < attribute_data_.size(); ++i) {
|
||||||
|
const bool is_seam = traversal_decoder_.DecodeAttributeSeam(i);
|
||||||
|
if (is_seam)
|
||||||
|
attribute_data_[i].attribute_seam_corners.push_back(corners[c].value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
template <class TraversalDecoder>
|
template <class TraversalDecoder>
|
||||||
bool MeshEdgeBreakerDecoderImpl<TraversalDecoder>::AssignPointsToCorners() {
|
bool MeshEdgeBreakerDecoderImpl<TraversalDecoder>::AssignPointsToCorners() {
|
||||||
// Map between the existing and deduplicated point ids.
|
// Map between the existing and deduplicated point ids.
|
||||||
|
@ -111,6 +111,7 @@ class MeshEdgeBreakerDecoderImpl : public MeshEdgeBreakerDecoderImplInterface {
|
|||||||
|
|
||||||
// Decodes all non-position attribute connectivity on the currently
|
// Decodes all non-position attribute connectivity on the currently
|
||||||
// processed face.
|
// processed face.
|
||||||
|
bool DecodeAttributeConnectivitiesOnFaceLegacy(CornerIndex corner);
|
||||||
bool DecodeAttributeConnectivitiesOnFace(CornerIndex corner);
|
bool DecodeAttributeConnectivitiesOnFace(CornerIndex corner);
|
||||||
|
|
||||||
// Initializes mapping between corners and point ids.
|
// Initializes mapping between corners and point ids.
|
||||||
@ -149,9 +150,6 @@ class MeshEdgeBreakerDecoderImpl : public MeshEdgeBreakerDecoderImplInterface {
|
|||||||
// List of decoded hole events.
|
// List of decoded hole events.
|
||||||
std::vector<HoleEventData> hole_event_data_;
|
std::vector<HoleEventData> hole_event_data_;
|
||||||
|
|
||||||
// The number of processed hole events.
|
|
||||||
int num_processed_hole_events_;
|
|
||||||
|
|
||||||
// Configuration of the initial face for each mesh component.
|
// Configuration of the initial face for each mesh component.
|
||||||
std::vector<bool> init_face_configurations_;
|
std::vector<bool> init_face_configurations_;
|
||||||
|
|
||||||
|
@ -38,7 +38,8 @@ MeshEdgeBreakerEncoderImpl<TraversalEncoder>::MeshEdgeBreakerEncoderImpl()
|
|||||||
: encoder_(nullptr),
|
: encoder_(nullptr),
|
||||||
mesh_(nullptr),
|
mesh_(nullptr),
|
||||||
last_encoded_symbol_id_(-1),
|
last_encoded_symbol_id_(-1),
|
||||||
num_split_symbols_(0) {}
|
num_split_symbols_(0),
|
||||||
|
use_single_connectivity_(false) {}
|
||||||
|
|
||||||
template <class TraversalEncoder>
|
template <class TraversalEncoder>
|
||||||
bool MeshEdgeBreakerEncoderImpl<TraversalEncoder>::Init(
|
bool MeshEdgeBreakerEncoderImpl<TraversalEncoder>::Init(
|
||||||
@ -46,6 +47,16 @@ bool MeshEdgeBreakerEncoderImpl<TraversalEncoder>::Init(
|
|||||||
encoder_ = encoder;
|
encoder_ = encoder;
|
||||||
mesh_ = encoder->mesh();
|
mesh_ = encoder->mesh();
|
||||||
attribute_encoder_to_data_id_map_.clear();
|
attribute_encoder_to_data_id_map_.clear();
|
||||||
|
|
||||||
|
if (encoder_->options()->IsGlobalOptionSet("split_mesh_on_seams")) {
|
||||||
|
use_single_connectivity_ =
|
||||||
|
encoder_->options()->GetGlobalBool("split_mesh_on_seams", false);
|
||||||
|
} else if (encoder_->options()->GetSpeed() >= 6) {
|
||||||
|
// Else use default setting based on speed.
|
||||||
|
use_single_connectivity_ = true;
|
||||||
|
} else {
|
||||||
|
use_single_connectivity_ = false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,9 +112,16 @@ MeshEdgeBreakerEncoderImpl<TraversalEncoder>::CreateVertexTraversalSequencer(
|
|||||||
template <class TraversalEncoder>
|
template <class TraversalEncoder>
|
||||||
bool MeshEdgeBreakerEncoderImpl<TraversalEncoder>::GenerateAttributesEncoder(
|
bool MeshEdgeBreakerEncoderImpl<TraversalEncoder>::GenerateAttributesEncoder(
|
||||||
int32_t att_id) {
|
int32_t att_id) {
|
||||||
// For now, create one encoder for each attribute. Ideally we can share
|
// For now, either create one encoder for each attribute or use a single
|
||||||
// the same encoder for attributes with the same connectivity (this is
|
// encoder for all attributes. Ideally we can share the same encoder for
|
||||||
// especially true for per-vertex attributes).
|
// a sub-set of attributes with the same connectivity (this is especially true
|
||||||
|
// for per-vertex attributes).
|
||||||
|
if (use_single_connectivity_ && GetEncoder()->num_attributes_encoders() > 0) {
|
||||||
|
// We are using single connectivity and we already have an attribute
|
||||||
|
// encoder. Add the attribute to the encoder and return.
|
||||||
|
GetEncoder()->attributes_encoder(0)->AddAttributeId(att_id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
const int32_t element_type =
|
const int32_t element_type =
|
||||||
GetEncoder()->mesh()->GetAttributeElementType(att_id);
|
GetEncoder()->mesh()->GetAttributeElementType(att_id);
|
||||||
const PointAttribute *const att =
|
const PointAttribute *const att =
|
||||||
@ -117,7 +135,8 @@ bool MeshEdgeBreakerEncoderImpl<TraversalEncoder>::GenerateAttributesEncoder(
|
|||||||
}
|
}
|
||||||
MeshTraversalMethod traversal_method = MESH_TRAVERSAL_DEPTH_FIRST;
|
MeshTraversalMethod traversal_method = MESH_TRAVERSAL_DEPTH_FIRST;
|
||||||
std::unique_ptr<PointsSequencer> sequencer;
|
std::unique_ptr<PointsSequencer> sequencer;
|
||||||
if (att->attribute_type() == GeometryAttribute::POSITION ||
|
if (use_single_connectivity_ ||
|
||||||
|
att->attribute_type() == GeometryAttribute::POSITION ||
|
||||||
element_type == MESH_VERTEX_ATTRIBUTE ||
|
element_type == MESH_VERTEX_ATTRIBUTE ||
|
||||||
(element_type == MESH_CORNER_ATTRIBUTE &&
|
(element_type == MESH_CORNER_ATTRIBUTE &&
|
||||||
attribute_data_[att_data_id].connectivity_data.no_interior_seams())) {
|
attribute_data_[att_data_id].connectivity_data.no_interior_seams())) {
|
||||||
@ -127,20 +146,30 @@ bool MeshEdgeBreakerEncoderImpl<TraversalEncoder>::GenerateAttributesEncoder(
|
|||||||
typedef MeshAttributeIndicesEncodingObserver<CornerTable> AttObserver;
|
typedef MeshAttributeIndicesEncodingObserver<CornerTable> AttObserver;
|
||||||
|
|
||||||
MeshAttributeIndicesEncodingData *encoding_data;
|
MeshAttributeIndicesEncodingData *encoding_data;
|
||||||
if (att->attribute_type() == GeometryAttribute::POSITION) {
|
if (use_single_connectivity_ ||
|
||||||
|
att->attribute_type() == GeometryAttribute::POSITION) {
|
||||||
encoding_data = &pos_encoding_data_;
|
encoding_data = &pos_encoding_data_;
|
||||||
} else {
|
} else {
|
||||||
encoding_data = &attribute_data_[att_data_id].encoding_data;
|
encoding_data = &attribute_data_[att_data_id].encoding_data;
|
||||||
attribute_data_[att_data_id].is_connectivity_used = false;
|
attribute_data_[att_data_id].is_connectivity_used = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (att->attribute_type() == GeometryAttribute::POSITION &&
|
if (GetEncoder()->options()->GetSpeed() == 0 &&
|
||||||
GetEncoder()->options()->GetSpeed() == 0) {
|
att->attribute_type() == GeometryAttribute::POSITION) {
|
||||||
|
traversal_method = MESH_TRAVERSAL_PREDICTION_DEGREE;
|
||||||
|
if (use_single_connectivity_ && mesh_->num_attributes() > 1) {
|
||||||
|
// Make sure we don't use the prediction degree traversal when we encode
|
||||||
|
// multiple attributes using the same connectivity.
|
||||||
|
// TODO(ostava): We should investigate this and see if the prediction
|
||||||
|
// degree can be actually used efficiently for non-position attributes.
|
||||||
|
traversal_method = MESH_TRAVERSAL_DEPTH_FIRST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (traversal_method == MESH_TRAVERSAL_PREDICTION_DEGREE) {
|
||||||
// Traverser that is used to generate the encoding order of each
|
// Traverser that is used to generate the encoding order of each
|
||||||
// attribute.
|
// attribute.
|
||||||
typedef PredictionDegreeTraverser<AttProcessor, AttObserver> AttTraverser;
|
typedef PredictionDegreeTraverser<AttProcessor, AttObserver> AttTraverser;
|
||||||
sequencer = CreateVertexTraversalSequencer<AttTraverser>(encoding_data);
|
sequencer = CreateVertexTraversalSequencer<AttTraverser>(encoding_data);
|
||||||
traversal_method = MESH_TRAVERSAL_PREDICTION_DEGREE;
|
|
||||||
} else {
|
} else {
|
||||||
// Traverser that is used to generate the encoding order of each
|
// Traverser that is used to generate the encoding order of each
|
||||||
// attribute.
|
// attribute.
|
||||||
@ -230,8 +259,14 @@ bool MeshEdgeBreakerEncoderImpl<TraversalEncoder>::EncodeConnectivity() {
|
|||||||
// To encode the mesh, we need face connectivity data stored in a corner
|
// To encode the mesh, we need face connectivity data stored in a corner
|
||||||
// table. To compute the connectivity we must use indices associated with
|
// table. To compute the connectivity we must use indices associated with
|
||||||
// POSITION attribute, because they define which edges can be connected
|
// POSITION attribute, because they define which edges can be connected
|
||||||
// together.
|
// together, unless the option |use_single_connectivity_| is set in which case
|
||||||
corner_table_ = CreateCornerTable(mesh_);
|
// we break the mesh along attribute seams and use the same connectivity for
|
||||||
|
// all attributes.
|
||||||
|
if (use_single_connectivity_) {
|
||||||
|
corner_table_ = CreateCornerTableFromAllAttributes(mesh_);
|
||||||
|
} else {
|
||||||
|
corner_table_ = CreateCornerTable(mesh_);
|
||||||
|
}
|
||||||
if (corner_table_ == nullptr) {
|
if (corner_table_ == nullptr) {
|
||||||
// Failed to construct the corner table.
|
// Failed to construct the corner table.
|
||||||
return false;
|
return false;
|
||||||
@ -274,7 +309,6 @@ bool MeshEdgeBreakerEncoderImpl<TraversalEncoder>::EncodeConnectivity() {
|
|||||||
face_to_split_symbol_map_.clear();
|
face_to_split_symbol_map_.clear();
|
||||||
visited_holes_.clear();
|
visited_holes_.clear();
|
||||||
vertex_hole_id_.assign(corner_table_->num_vertices(), -1);
|
vertex_hole_id_.assign(corner_table_->num_vertices(), -1);
|
||||||
hole_event_data_.clear();
|
|
||||||
processed_connectivity_corners_.clear();
|
processed_connectivity_corners_.clear();
|
||||||
processed_connectivity_corners_.reserve(corner_table_->num_faces());
|
processed_connectivity_corners_.reserve(corner_table_->num_faces());
|
||||||
pos_encoding_data_.num_values = 0;
|
pos_encoding_data_.num_values = 0;
|
||||||
@ -287,6 +321,7 @@ bool MeshEdgeBreakerEncoderImpl<TraversalEncoder>::EncodeConnectivity() {
|
|||||||
|
|
||||||
const int8_t num_attribute_data = attribute_data_.size();
|
const int8_t num_attribute_data = attribute_data_.size();
|
||||||
encoder_->buffer()->Encode(num_attribute_data);
|
encoder_->buffer()->Encode(num_attribute_data);
|
||||||
|
traversal_encoder_.SetNumAttributeData(num_attribute_data);
|
||||||
|
|
||||||
const int num_corners = corner_table_->num_corners();
|
const int num_corners = corner_table_->num_corners();
|
||||||
|
|
||||||
@ -361,6 +396,7 @@ bool MeshEdgeBreakerEncoderImpl<TraversalEncoder>::EncodeConnectivity() {
|
|||||||
// Encode connectivity for all non-position attributes.
|
// Encode connectivity for all non-position attributes.
|
||||||
if (attribute_data_.size() > 0) {
|
if (attribute_data_.size() > 0) {
|
||||||
// Use the same order of corner that will be used by the decoder.
|
// Use the same order of corner that will be used by the decoder.
|
||||||
|
visited_faces_.assign(mesh_->num_faces(), false);
|
||||||
for (CornerIndex ci : processed_connectivity_corners_) {
|
for (CornerIndex ci : processed_connectivity_corners_) {
|
||||||
EncodeAttributeConnectivitiesOnFace(ci);
|
EncodeAttributeConnectivitiesOnFace(ci);
|
||||||
}
|
}
|
||||||
@ -413,19 +449,6 @@ bool MeshEdgeBreakerEncoderImpl<TraversalEncoder>::EncodeConnectivity() {
|
|||||||
}
|
}
|
||||||
encoder_->buffer()->EndBitEncoding();
|
encoder_->buffer()->EndBitEncoding();
|
||||||
}
|
}
|
||||||
// Encode hole events data.
|
|
||||||
num_events = hole_event_data_.size();
|
|
||||||
EncodeVarint(num_events, encoder_->buffer());
|
|
||||||
if (num_events > 0) {
|
|
||||||
// Encode hole symbol ids using delta and varint coding. The symbol ids are
|
|
||||||
// always stored in increasing order so the deltas are going to be positive.
|
|
||||||
int last_symbol_id = 0;
|
|
||||||
for (uint32_t i = 0; i < num_events; ++i) {
|
|
||||||
EncodeVarint<uint32_t>(hole_event_data_[i].symbol_id - last_symbol_id,
|
|
||||||
encoder_->buffer());
|
|
||||||
last_symbol_id = hole_event_data_[i].symbol_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -552,8 +575,6 @@ bool MeshEdgeBreakerEncoderImpl<TraversalEncoder>::EncodeConnectivityFromCorner(
|
|||||||
const int hole_id = vertex_hole_id_[vert_id.value()];
|
const int hole_id = vertex_hole_id_[vert_id.value()];
|
||||||
if (!visited_holes_[hole_id]) {
|
if (!visited_holes_[hole_id]) {
|
||||||
EncodeHole(corner_id, false);
|
EncodeHole(corner_id, false);
|
||||||
hole_event_data_.push_back(
|
|
||||||
HoleEventData(last_encoded_symbol_id_));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
face_to_split_symbol_map_[face_id.value()] = last_encoded_symbol_id_;
|
face_to_split_symbol_map_[face_id.value()] = last_encoded_symbol_id_;
|
||||||
@ -732,6 +753,9 @@ void MeshEdgeBreakerEncoderImpl<
|
|||||||
|
|
||||||
template <class TraversalEncoder>
|
template <class TraversalEncoder>
|
||||||
bool MeshEdgeBreakerEncoderImpl<TraversalEncoder>::InitAttributeData() {
|
bool MeshEdgeBreakerEncoderImpl<TraversalEncoder>::InitAttributeData() {
|
||||||
|
if (use_single_connectivity_)
|
||||||
|
return true; // All attributes use the same connectivity.
|
||||||
|
|
||||||
const int num_attributes = mesh_->num_attributes();
|
const int num_attributes = mesh_->num_attributes();
|
||||||
// Ignore the position attribute. It's decoded separately.
|
// Ignore the position attribute. It's decoded separately.
|
||||||
attribute_data_.resize(num_attributes - 1);
|
attribute_data_.resize(num_attributes - 1);
|
||||||
@ -773,10 +797,16 @@ bool MeshEdgeBreakerEncoderImpl<
|
|||||||
const CornerIndex corners[3] = {corner, corner_table_->Next(corner),
|
const CornerIndex corners[3] = {corner, corner_table_->Next(corner),
|
||||||
corner_table_->Previous(corner)};
|
corner_table_->Previous(corner)};
|
||||||
|
|
||||||
|
const FaceIndex src_face_id = corner_table_->Face(corner);
|
||||||
|
visited_faces_[src_face_id.value()] = true;
|
||||||
for (int c = 0; c < 3; ++c) {
|
for (int c = 0; c < 3; ++c) {
|
||||||
const CornerIndex opp_corner = corner_table_->Opposite(corners[c]);
|
const CornerIndex opp_corner = corner_table_->Opposite(corners[c]);
|
||||||
if (opp_corner < 0)
|
if (opp_corner < 0)
|
||||||
continue; // Don't encode attribute seams on boundary edges.
|
continue; // Don't encode attribute seams on boundary edges.
|
||||||
|
const FaceIndex opp_face_id = corner_table_->Face(opp_corner);
|
||||||
|
// Don't encode edges when the opposite face has been already processed.
|
||||||
|
if (visited_faces_[opp_face_id.value()])
|
||||||
|
continue;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < attribute_data_.size(); ++i) {
|
for (uint32_t i = 0; i < attribute_data_.size(); ++i) {
|
||||||
if (attribute_data_[i].connectivity_data.IsCornerOppositeToSeamEdge(
|
if (attribute_data_[i].connectivity_data.IsCornerOppositeToSeamEdge(
|
||||||
|
@ -164,9 +164,6 @@ class MeshEdgeBreakerEncoderImpl : public MeshEdgeBreakerEncoderImplInterface {
|
|||||||
// Array for mapping vertices to hole ids. If a vertex is not on a hole, the
|
// Array for mapping vertices to hole ids. If a vertex is not on a hole, the
|
||||||
// stored value is -1.
|
// stored value is -1.
|
||||||
std::vector<int> vertex_hole_id_;
|
std::vector<int> vertex_hole_id_;
|
||||||
// Array of hole events encountered during the traversal. There will be always
|
|
||||||
// exactly one hole event for each hole in the input mesh.
|
|
||||||
std::vector<HoleEventData> hole_event_data_;
|
|
||||||
|
|
||||||
// Id of the last encoded symbol.
|
// Id of the last encoded symbol.
|
||||||
int last_encoded_symbol_id_;
|
int last_encoded_symbol_id_;
|
||||||
@ -194,6 +191,13 @@ class MeshEdgeBreakerEncoderImpl : public MeshEdgeBreakerEncoderImplInterface {
|
|||||||
std::vector<int32_t> attribute_encoder_to_data_id_map_;
|
std::vector<int32_t> attribute_encoder_to_data_id_map_;
|
||||||
|
|
||||||
TraversalEncoderT traversal_encoder_;
|
TraversalEncoderT traversal_encoder_;
|
||||||
|
|
||||||
|
// If set, the encoder is going to use the same connectivity for all
|
||||||
|
// attributes. This effectively breaks the mesh along all attribute seams.
|
||||||
|
// In general, this approach should be much faster compared to encoding each
|
||||||
|
// connectivity separately, but the decoded model may contain higher number of
|
||||||
|
// duplicate attribute values which may decrease the compression ratio.
|
||||||
|
bool use_single_connectivity_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace draco
|
} // namespace draco
|
||||||
|
@ -150,4 +150,43 @@ TEST_F(MeshEdgebreakerEncodingTest, TestDecoderReuse) {
|
|||||||
<< "Decoded meshes are not the same";
|
<< "Decoded meshes are not the same";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(MeshEdgebreakerEncodingTest, TestSingleConnectivityEncoding) {
|
||||||
|
// Tests whether the edgebreaker method successfully encodes a mesh with
|
||||||
|
// multiple attributes using single connectivity by breaking the mesh along
|
||||||
|
// attribute seams.
|
||||||
|
const std::string file_name = "cube_att.obj";
|
||||||
|
const std::string path = GetTestFileFullPath(file_name);
|
||||||
|
const std::unique_ptr<Mesh> mesh(ReadMeshFromFile(path));
|
||||||
|
ASSERT_NE(mesh, nullptr) << "Failed to load test model " << file_name;
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
|
// Set the option to enable/disable single connectivity encoding.
|
||||||
|
EncoderOptionsBase<GeometryAttribute::Type> options =
|
||||||
|
EncoderOptionsBase<GeometryAttribute::Type>::CreateDefaultOptions();
|
||||||
|
options.SetGlobalBool("split_mesh_on_seams", i == 0 ? true : false);
|
||||||
|
|
||||||
|
EncoderBuffer buffer;
|
||||||
|
draco::Encoder encoder;
|
||||||
|
encoder.Reset(options);
|
||||||
|
encoder.SetSpeedOptions(0, 0);
|
||||||
|
encoder.SetAttributeQuantization(GeometryAttribute::POSITION, 8);
|
||||||
|
encoder.SetAttributeQuantization(GeometryAttribute::TEX_COORD, 8);
|
||||||
|
encoder.SetAttributeQuantization(GeometryAttribute::NORMAL, 8);
|
||||||
|
encoder.SetEncodingMethod(MESH_EDGEBREAKER_ENCODING);
|
||||||
|
ASSERT_TRUE(encoder.EncodeMeshToBuffer(*mesh, &buffer).ok());
|
||||||
|
|
||||||
|
DecoderBuffer dec_buffer;
|
||||||
|
dec_buffer.Init(buffer.data(), buffer.size());
|
||||||
|
|
||||||
|
Decoder decoder;
|
||||||
|
auto dec_mesh = decoder.DecodeMeshFromBuffer(&dec_buffer).value();
|
||||||
|
ASSERT_NE(dec_mesh, nullptr);
|
||||||
|
ASSERT_EQ(dec_mesh->num_points(), 24);
|
||||||
|
ASSERT_EQ(dec_mesh->num_attributes(), 3);
|
||||||
|
ASSERT_EQ(dec_mesh->attribute(0)->size(), i == 0 ? 24 : 8);
|
||||||
|
ASSERT_EQ(dec_mesh->attribute(1)->size(), 24);
|
||||||
|
ASSERT_EQ(dec_mesh->attribute(2)->size(), 24);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace draco
|
} // namespace draco
|
||||||
|
@ -31,24 +31,30 @@ typedef RAnsBitEncoder BinaryEncoder;
|
|||||||
class MeshEdgeBreakerTraversalEncoder {
|
class MeshEdgeBreakerTraversalEncoder {
|
||||||
public:
|
public:
|
||||||
MeshEdgeBreakerTraversalEncoder()
|
MeshEdgeBreakerTraversalEncoder()
|
||||||
: encoder_impl_(nullptr), attribute_connectivity_encoders_(nullptr) {}
|
: encoder_impl_(nullptr),
|
||||||
|
attribute_connectivity_encoders_(nullptr),
|
||||||
|
num_attribute_data_(0) {}
|
||||||
bool Init(MeshEdgeBreakerEncoderImplInterface *encoder) {
|
bool Init(MeshEdgeBreakerEncoderImplInterface *encoder) {
|
||||||
encoder_impl_ = encoder;
|
encoder_impl_ = encoder;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the number of non-position attribute data for which we need to encode
|
||||||
|
// the connectivity.
|
||||||
|
void SetNumAttributeData(int num_data) { num_attribute_data_ = num_data; }
|
||||||
|
|
||||||
// Called before the traversal encoding is started.
|
// Called before the traversal encoding is started.
|
||||||
void Start() {
|
void Start() {
|
||||||
const Mesh *const mesh = encoder_impl_->GetEncoder()->mesh();
|
const Mesh *const mesh = encoder_impl_->GetEncoder()->mesh();
|
||||||
// Allocate enough storage to store initial face configurations. This can
|
// Allocate enough storage to store initial face configurations. This can
|
||||||
// consume at most 1 bit per face if all faces are isolated.
|
// consume at most 1 bit per face if all faces are isolated.
|
||||||
start_face_buffer_.StartBitEncoding(mesh->num_faces(), true);
|
start_face_buffer_.StartBitEncoding(mesh->num_faces(), true);
|
||||||
if (mesh->num_attributes() > 1) {
|
if (num_attribute_data_ > 0) {
|
||||||
// Init and start arithmetic encoders for storing configuration types
|
// Init and start arithmetic encoders for storing configuration types
|
||||||
// of non-position attributes.
|
// of non-position attributes.
|
||||||
attribute_connectivity_encoders_ = std::unique_ptr<BinaryEncoder[]>(
|
attribute_connectivity_encoders_ = std::unique_ptr<BinaryEncoder[]>(
|
||||||
new BinaryEncoder[mesh->num_attributes() - 1]);
|
new BinaryEncoder[num_attribute_data_]);
|
||||||
for (int i = 0; i < mesh->num_attributes() - 1; ++i) {
|
for (int i = 0; i < num_attribute_data_; ++i) {
|
||||||
attribute_connectivity_encoders_[i].StartEncoding();
|
attribute_connectivity_encoders_[i].StartEncoding();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,8 +98,7 @@ class MeshEdgeBreakerTraversalEncoder {
|
|||||||
traversal_buffer_.Encode(start_face_buffer_.data(),
|
traversal_buffer_.Encode(start_face_buffer_.data(),
|
||||||
start_face_buffer_.size());
|
start_face_buffer_.size());
|
||||||
if (attribute_connectivity_encoders_ != nullptr) {
|
if (attribute_connectivity_encoders_ != nullptr) {
|
||||||
const Mesh *const mesh = encoder_impl_->GetEncoder()->mesh();
|
for (int i = 0; i < num_attribute_data_; ++i) {
|
||||||
for (int i = 0; i < mesh->num_attributes() - 1; ++i) {
|
|
||||||
attribute_connectivity_encoders_[i].EndEncoding(&traversal_buffer_);
|
attribute_connectivity_encoders_[i].EndEncoding(&traversal_buffer_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,6 +125,7 @@ class MeshEdgeBreakerTraversalEncoder {
|
|||||||
// Arithmetic encoder for encoding attribute seams.
|
// Arithmetic encoder for encoding attribute seams.
|
||||||
// One context for each non-position attribute.
|
// One context for each non-position attribute.
|
||||||
std::unique_ptr<BinaryEncoder[]> attribute_connectivity_encoders_;
|
std::unique_ptr<BinaryEncoder[]> attribute_connectivity_encoders_;
|
||||||
|
int num_attribute_data_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace draco
|
} // namespace draco
|
||||||
|
@ -63,12 +63,13 @@ TEST_P(MeshEncoderTest, EncodeGoldenMesh) {
|
|||||||
std::string golden_file_name = file_name;
|
std::string golden_file_name = file_name;
|
||||||
golden_file_name += '.';
|
golden_file_name += '.';
|
||||||
golden_file_name += GetParam();
|
golden_file_name += GetParam();
|
||||||
golden_file_name += ".1.0.0.drc";
|
golden_file_name += ".1.1.0.drc";
|
||||||
const std::unique_ptr<Mesh> mesh(DecodeObj(file_name));
|
const std::unique_ptr<Mesh> mesh(DecodeObj(file_name));
|
||||||
ASSERT_NE(mesh, nullptr) << "Failed to load test model " << file_name;
|
ASSERT_NE(mesh, nullptr) << "Failed to load test model " << file_name;
|
||||||
|
|
||||||
ExpertEncoder encoder(*mesh.get());
|
ExpertEncoder encoder(*mesh.get());
|
||||||
encoder.SetEncodingMethod(method);
|
encoder.SetEncodingMethod(method);
|
||||||
|
encoder.SetAttributeQuantization(0, 20);
|
||||||
EncoderBuffer buffer;
|
EncoderBuffer buffer;
|
||||||
ASSERT_TRUE(encoder.EncodeToBuffer(&buffer).ok())
|
ASSERT_TRUE(encoder.EncodeToBuffer(&buffer).ok())
|
||||||
<< "Failed encoding test mesh " << file_name << " with method "
|
<< "Failed encoding test mesh " << file_name << " with method "
|
||||||
|
@ -172,7 +172,7 @@ static inline int rabs_desc_read(struct AnsDecoder *ans, AnsP8 p0) {
|
|||||||
unsigned quot, rem, x, xn;
|
unsigned quot, rem, x, xn;
|
||||||
#endif
|
#endif
|
||||||
const AnsP8 p = ans_p8_precision - p0;
|
const AnsP8 p = ans_p8_precision - p0;
|
||||||
if (ans->state < l_base) {
|
if (ans->state < l_base && ans->buf_offset > 0) {
|
||||||
ans->state = ans->state * io_base + ans->buf[--ans->buf_offset];
|
ans->state = ans->state * io_base + ans->buf[--ans->buf_offset];
|
||||||
}
|
}
|
||||||
#if ANS_IMPL1
|
#if ANS_IMPL1
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
namespace draco {
|
namespace draco {
|
||||||
|
|
||||||
// Draco version is comprised of <major>.<minor>.<revision>.
|
// Draco version is comprised of <major>.<minor>.<revision>.
|
||||||
static const char kDracoVersion[] = "1.0.1";
|
static const char kDracoVersion[] = "1.1.0";
|
||||||
|
|
||||||
const char *Version() { return kDracoVersion; }
|
const char *Version() { return kDracoVersion; }
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ ObjDecoder::ObjDecoder()
|
|||||||
num_positions_(0),
|
num_positions_(0),
|
||||||
num_tex_coords_(0),
|
num_tex_coords_(0),
|
||||||
num_normals_(0),
|
num_normals_(0),
|
||||||
num_sub_objects_(0),
|
last_sub_obj_id_(0),
|
||||||
pos_att_id_(-1),
|
pos_att_id_(-1),
|
||||||
tex_att_id_(-1),
|
tex_att_id_(-1),
|
||||||
norm_att_id_(-1),
|
norm_att_id_(-1),
|
||||||
@ -37,7 +37,6 @@ ObjDecoder::ObjDecoder()
|
|||||||
sub_obj_att_id_(-1),
|
sub_obj_att_id_(-1),
|
||||||
deduplicate_input_values_(true),
|
deduplicate_input_values_(true),
|
||||||
last_material_id_(0),
|
last_material_id_(0),
|
||||||
open_material_file_(false),
|
|
||||||
use_metadata_(false),
|
use_metadata_(false),
|
||||||
out_mesh_(nullptr),
|
out_mesh_(nullptr),
|
||||||
out_point_cloud_(nullptr) {}
|
out_point_cloud_(nullptr) {}
|
||||||
@ -65,7 +64,6 @@ bool ObjDecoder::DecodeFromFile(const std::string &file_name,
|
|||||||
buffer_.Init(&data[0], file_size);
|
buffer_.Init(&data[0], file_size);
|
||||||
|
|
||||||
out_point_cloud_ = out_point_cloud;
|
out_point_cloud_ = out_point_cloud;
|
||||||
open_material_file_ = true;
|
|
||||||
input_file_name_ = file_name;
|
input_file_name_ = file_name;
|
||||||
return DecodeInternal();
|
return DecodeInternal();
|
||||||
}
|
}
|
||||||
@ -79,7 +77,6 @@ bool ObjDecoder::DecodeFromBuffer(DecoderBuffer *buffer,
|
|||||||
PointCloud *out_point_cloud) {
|
PointCloud *out_point_cloud) {
|
||||||
out_point_cloud_ = out_point_cloud;
|
out_point_cloud_ = out_point_cloud;
|
||||||
buffer_.Init(buffer->data_head(), buffer->remaining_size());
|
buffer_.Init(buffer->data_head(), buffer->remaining_size());
|
||||||
open_material_file_ = false;
|
|
||||||
return DecodeInternal();
|
return DecodeInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +88,7 @@ bool ObjDecoder::DecodeInternal() {
|
|||||||
counting_mode_ = true;
|
counting_mode_ = true;
|
||||||
ResetCounters();
|
ResetCounters();
|
||||||
material_name_to_id_.clear();
|
material_name_to_id_.clear();
|
||||||
num_sub_objects_ = 0;
|
last_sub_obj_id_ = 0;
|
||||||
// Parse all lines.
|
// Parse all lines.
|
||||||
bool error = false;
|
bool error = false;
|
||||||
while (ParseDefinition(&error) && !error) {
|
while (ParseDefinition(&error) && !error) {
|
||||||
@ -156,22 +153,24 @@ bool ObjDecoder::DecodeInternal() {
|
|||||||
const AttributeValueIndex i(itr.second);
|
const AttributeValueIndex i(itr.second);
|
||||||
material_metadata->AddEntryInt(itr.first, itr.second);
|
material_metadata->AddEntryInt(itr.first, itr.second);
|
||||||
}
|
}
|
||||||
material_metadata->AddEntryString("file_name", material_file_name_);
|
if (!material_file_name_.empty()) {
|
||||||
|
material_metadata->AddEntryString("file_name", material_file_name_);
|
||||||
|
}
|
||||||
|
|
||||||
out_point_cloud_->AddAttributeMetadata(std::move(material_metadata));
|
out_point_cloud_->AddAttributeMetadata(std::move(material_metadata));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (num_sub_objects_ > 1) {
|
if (!obj_name_to_id_.empty()) {
|
||||||
GeometryAttribute va;
|
GeometryAttribute va;
|
||||||
if (num_sub_objects_ < 256) {
|
if (obj_name_to_id_.size() < 256) {
|
||||||
va.Init(GeometryAttribute::GENERIC, nullptr, 1, DT_UINT8, false, 1, 0);
|
va.Init(GeometryAttribute::GENERIC, nullptr, 1, DT_UINT8, false, 1, 0);
|
||||||
} else if (num_sub_objects_ < (1 << 16)) {
|
} else if (obj_name_to_id_.size() < (1 << 16)) {
|
||||||
va.Init(GeometryAttribute::GENERIC, nullptr, 1, DT_UINT16, false, 2, 0);
|
va.Init(GeometryAttribute::GENERIC, nullptr, 1, DT_UINT16, false, 2, 0);
|
||||||
} else {
|
} else {
|
||||||
va.Init(GeometryAttribute::GENERIC, nullptr, 1, DT_UINT32, false, 4, 0);
|
va.Init(GeometryAttribute::GENERIC, nullptr, 1, DT_UINT32, false, 4, 0);
|
||||||
}
|
}
|
||||||
sub_obj_att_id_ =
|
sub_obj_att_id_ =
|
||||||
out_point_cloud_->AddAttribute(va, false, num_sub_objects_);
|
out_point_cloud_->AddAttribute(va, false, obj_name_to_id_.size());
|
||||||
// Fill the sub object id entries.
|
// Fill the sub object id entries.
|
||||||
for (const auto &itr : obj_name_to_id_) {
|
for (const auto &itr : obj_name_to_id_) {
|
||||||
const AttributeValueIndex i(itr.second);
|
const AttributeValueIndex i(itr.second);
|
||||||
@ -224,7 +223,7 @@ void ObjDecoder::ResetCounters() {
|
|||||||
num_tex_coords_ = 0;
|
num_tex_coords_ = 0;
|
||||||
num_normals_ = 0;
|
num_normals_ = 0;
|
||||||
last_material_id_ = 0;
|
last_material_id_ = 0;
|
||||||
num_sub_objects_ = 0;
|
last_sub_obj_id_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ObjDecoder::ParseDefinition(bool *error) {
|
bool ObjDecoder::ParseDefinition(bool *error) {
|
||||||
@ -419,9 +418,6 @@ bool ObjDecoder::ParseMaterialLib(bool *error) {
|
|||||||
// Allow only one material library per file for now.
|
// Allow only one material library per file for now.
|
||||||
if (material_name_to_id_.size() > 0)
|
if (material_name_to_id_.size() > 0)
|
||||||
return false;
|
return false;
|
||||||
// Skip the parsing if we don't want to open material files.
|
|
||||||
if (!open_material_file_)
|
|
||||||
return false;
|
|
||||||
std::array<char, 6> c;
|
std::array<char, 6> c;
|
||||||
if (!buffer()->Peek(&c)) {
|
if (!buffer()->Peek(&c)) {
|
||||||
return false;
|
return false;
|
||||||
@ -447,10 +443,9 @@ bool ObjDecoder::ParseMaterialLib(bool *error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ObjDecoder::ParseMaterial(bool * /* error */) {
|
bool ObjDecoder::ParseMaterial(bool * /* error */) {
|
||||||
if (counting_mode_)
|
// In second pass, skip when we don't use materials.
|
||||||
return false; // Skip when we are counting definitions.
|
if (!counting_mode_ && material_att_id_ < 0)
|
||||||
if (material_att_id_ < 0)
|
return false;
|
||||||
return false; // Don't parse it when we don't use materials.
|
|
||||||
std::array<char, 6> c;
|
std::array<char, 6> c;
|
||||||
if (!buffer()->Peek(&c)) {
|
if (!buffer()->Peek(&c)) {
|
||||||
return false;
|
return false;
|
||||||
@ -464,7 +459,11 @@ bool ObjDecoder::ParseMaterial(bool * /* error */) {
|
|||||||
return false;
|
return false;
|
||||||
auto it = material_name_to_id_.find(mat_name);
|
auto it = material_name_to_id_.find(mat_name);
|
||||||
if (it == material_name_to_id_.end()) {
|
if (it == material_name_to_id_.end()) {
|
||||||
// Invalid material..ignore.
|
// In first pass, materials found in obj that's not in the .mtl file
|
||||||
|
// will be added to the list.
|
||||||
|
const size_t num_mat = material_name_to_id_.size();
|
||||||
|
material_name_to_id_[mat_name] = num_mat;
|
||||||
|
last_material_id_ = num_mat;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
last_material_id_ = it->second;
|
last_material_id_ = it->second;
|
||||||
@ -485,10 +484,11 @@ bool ObjDecoder::ParseObject(bool *error) {
|
|||||||
return false;
|
return false;
|
||||||
auto it = obj_name_to_id_.find(obj_name);
|
auto it = obj_name_to_id_.find(obj_name);
|
||||||
if (it == obj_name_to_id_.end()) {
|
if (it == obj_name_to_id_.end()) {
|
||||||
obj_name_to_id_[obj_name] = num_sub_objects_;
|
const int num_obj = obj_name_to_id_.size();
|
||||||
num_sub_objects_++;
|
obj_name_to_id_[obj_name] = num_obj;
|
||||||
|
last_sub_obj_id_ = num_obj;
|
||||||
} else {
|
} else {
|
||||||
num_sub_objects_ = it->second + 1;
|
last_sub_obj_id_ = it->second;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -584,9 +584,8 @@ void ObjDecoder::MapPointToVertexIndices(
|
|||||||
|
|
||||||
// Assign sub-object index to the point if it is available.
|
// Assign sub-object index to the point if it is available.
|
||||||
if (sub_obj_att_id_ >= 0) {
|
if (sub_obj_att_id_ >= 0) {
|
||||||
const int sub_obj_id = num_sub_objects_ > 0 ? num_sub_objects_ - 1 : 0;
|
|
||||||
out_point_cloud_->attribute(sub_obj_att_id_)
|
out_point_cloud_->attribute(sub_obj_att_id_)
|
||||||
->SetPointMapEntry(vert_id, AttributeValueIndex(sub_obj_id));
|
->SetPointMapEntry(vert_id, AttributeValueIndex(last_sub_obj_id_));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -642,8 +641,7 @@ bool ObjDecoder::ParseMaterialFileDefinition(bool * /* error */) {
|
|||||||
return false;
|
return false;
|
||||||
if (str.compare("newmtl") == 0) {
|
if (str.compare("newmtl") == 0) {
|
||||||
parser::SkipWhitespace(buffer());
|
parser::SkipWhitespace(buffer());
|
||||||
if (!parser::ParseString(buffer(), &str))
|
parser::ParseLine(buffer(), &str);
|
||||||
return false;
|
|
||||||
// Add new material to our map.
|
// Add new material to our map.
|
||||||
const size_t material_name_id = material_name_to_id_.size();
|
const size_t material_name_id = material_name_to_id_.size();
|
||||||
material_name_to_id_[str] = material_name_id;
|
material_name_to_id_[str] = material_name_id;
|
||||||
|
@ -93,7 +93,7 @@ class ObjDecoder {
|
|||||||
int num_positions_;
|
int num_positions_;
|
||||||
int num_tex_coords_;
|
int num_tex_coords_;
|
||||||
int num_normals_;
|
int num_normals_;
|
||||||
int num_sub_objects_;
|
int last_sub_obj_id_;
|
||||||
|
|
||||||
int pos_att_id_;
|
int pos_att_id_;
|
||||||
int tex_att_id_;
|
int tex_att_id_;
|
||||||
@ -106,7 +106,6 @@ class ObjDecoder {
|
|||||||
int last_material_id_;
|
int last_material_id_;
|
||||||
std::string material_file_name_;
|
std::string material_file_name_;
|
||||||
|
|
||||||
bool open_material_file_;
|
|
||||||
std::string input_file_name_;
|
std::string input_file_name_;
|
||||||
|
|
||||||
std::unordered_map<std::string, int> material_name_to_id_;
|
std::unordered_map<std::string, int> material_name_to_id_;
|
||||||
|
@ -16,15 +16,21 @@
|
|||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
#include "draco/metadata/geometry_metadata.h"
|
||||||
|
|
||||||
namespace draco {
|
namespace draco {
|
||||||
|
|
||||||
ObjEncoder::ObjEncoder()
|
ObjEncoder::ObjEncoder()
|
||||||
: pos_att_(nullptr),
|
: pos_att_(nullptr),
|
||||||
tex_coord_att_(nullptr),
|
tex_coord_att_(nullptr),
|
||||||
normal_att_(nullptr),
|
normal_att_(nullptr),
|
||||||
|
material_att_(nullptr),
|
||||||
|
sub_obj_att_(nullptr),
|
||||||
out_buffer_(nullptr),
|
out_buffer_(nullptr),
|
||||||
in_point_cloud_(nullptr),
|
in_point_cloud_(nullptr),
|
||||||
in_mesh_(nullptr) {}
|
in_mesh_(nullptr),
|
||||||
|
current_sub_obj_id_(-1),
|
||||||
|
current_material_id_(-1) {}
|
||||||
|
|
||||||
bool ObjEncoder::EncodeToFile(const PointCloud &pc,
|
bool ObjEncoder::EncodeToFile(const PointCloud &pc,
|
||||||
const std::string &file_name) {
|
const std::string &file_name) {
|
||||||
@ -63,6 +69,14 @@ bool ObjEncoder::EncodeInternal() {
|
|||||||
pos_att_ = nullptr;
|
pos_att_ = nullptr;
|
||||||
tex_coord_att_ = nullptr;
|
tex_coord_att_ = nullptr;
|
||||||
normal_att_ = nullptr;
|
normal_att_ = nullptr;
|
||||||
|
material_att_ = nullptr;
|
||||||
|
sub_obj_att_ = nullptr;
|
||||||
|
current_sub_obj_id_ = -1;
|
||||||
|
current_material_id_ = -1;
|
||||||
|
if (!GetSubObjects())
|
||||||
|
return false;
|
||||||
|
if (!EncodeMaterialFileName())
|
||||||
|
return false;
|
||||||
if (!EncodePositions())
|
if (!EncodePositions())
|
||||||
return false;
|
return false;
|
||||||
if (!EncodeTextureCoordinates())
|
if (!EncodeTextureCoordinates())
|
||||||
@ -81,9 +95,66 @@ bool ObjEncoder::ExitAndCleanup(bool return_value) {
|
|||||||
pos_att_ = nullptr;
|
pos_att_ = nullptr;
|
||||||
tex_coord_att_ = nullptr;
|
tex_coord_att_ = nullptr;
|
||||||
normal_att_ = nullptr;
|
normal_att_ = nullptr;
|
||||||
|
material_att_ = nullptr;
|
||||||
|
sub_obj_att_ = nullptr;
|
||||||
|
current_sub_obj_id_ = -1;
|
||||||
|
current_material_id_ = -1;
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ObjEncoder::GetSubObjects() {
|
||||||
|
const GeometryMetadata *pc_metadata = in_point_cloud_->GetMetadata();
|
||||||
|
if (!pc_metadata)
|
||||||
|
return true;
|
||||||
|
const AttributeMetadata *sub_obj_metadata =
|
||||||
|
pc_metadata->GetAttributeMetadataByStringEntry("name", "sub_obj");
|
||||||
|
if (!sub_obj_metadata)
|
||||||
|
return true;
|
||||||
|
sub_obj_id_to_name_.clear();
|
||||||
|
for (const auto &entry : sub_obj_metadata->entries()) {
|
||||||
|
// Sub-object id must be int.
|
||||||
|
int value = 0;
|
||||||
|
if (!entry.second.GetValue(&value))
|
||||||
|
continue;
|
||||||
|
sub_obj_id_to_name_[value] = entry.first;
|
||||||
|
}
|
||||||
|
const int sub_obj_att_id = sub_obj_metadata->attribute_id();
|
||||||
|
sub_obj_att_ = in_point_cloud_->attribute(sub_obj_att_id);
|
||||||
|
if (sub_obj_att_ == nullptr || sub_obj_att_->size() == 0)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjEncoder::EncodeMaterialFileName() {
|
||||||
|
const GeometryMetadata *pc_metadata = in_point_cloud_->GetMetadata();
|
||||||
|
if (!pc_metadata)
|
||||||
|
return true;
|
||||||
|
const AttributeMetadata *material_metadata =
|
||||||
|
pc_metadata->GetAttributeMetadataByStringEntry("name", "material");
|
||||||
|
if (!material_metadata)
|
||||||
|
return true;
|
||||||
|
std::string material_file_name;
|
||||||
|
if (!material_metadata->GetEntryString("file_name", &material_file_name))
|
||||||
|
return false;
|
||||||
|
buffer()->Encode("mtllib ", 7);
|
||||||
|
buffer()->Encode(material_file_name.c_str(), material_file_name.size());
|
||||||
|
buffer()->Encode("\n", 1);
|
||||||
|
material_id_to_name_.clear();
|
||||||
|
for (const auto &entry : material_metadata->entries()) {
|
||||||
|
// Material id must be int.
|
||||||
|
int value = 0;
|
||||||
|
// Found entry that are not material id, e.g. file name as a string.
|
||||||
|
if (!entry.second.GetValue(&value))
|
||||||
|
continue;
|
||||||
|
material_id_to_name_[value] = entry.first;
|
||||||
|
}
|
||||||
|
const int material_att_id = material_metadata->attribute_id();
|
||||||
|
material_att_ = in_point_cloud_->attribute(material_att_id);
|
||||||
|
if (material_att_ == nullptr || material_att_->size() == 0)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ObjEncoder::EncodePositions() {
|
bool ObjEncoder::EncodePositions() {
|
||||||
const PointAttribute *const att =
|
const PointAttribute *const att =
|
||||||
in_point_cloud_->GetNamedAttribute(GeometryAttribute::POSITION);
|
in_point_cloud_->GetNamedAttribute(GeometryAttribute::POSITION);
|
||||||
@ -137,6 +208,12 @@ bool ObjEncoder::EncodeNormals() {
|
|||||||
|
|
||||||
bool ObjEncoder::EncodeFaces() {
|
bool ObjEncoder::EncodeFaces() {
|
||||||
for (FaceIndex i(0); i < in_mesh_->num_faces(); ++i) {
|
for (FaceIndex i(0); i < in_mesh_->num_faces(); ++i) {
|
||||||
|
if (sub_obj_att_)
|
||||||
|
if (!EncodeSubObject(i))
|
||||||
|
return false;
|
||||||
|
if (material_att_)
|
||||||
|
if (!EncodeMaterial(i))
|
||||||
|
return false;
|
||||||
buffer()->Encode('f');
|
buffer()->Encode('f');
|
||||||
for (int j = 0; j < 3; ++j) {
|
for (int j = 0; j < 3; ++j) {
|
||||||
if (!EncodeFaceCorner(i, j))
|
if (!EncodeFaceCorner(i, j))
|
||||||
@ -147,6 +224,49 @@ bool ObjEncoder::EncodeFaces() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ObjEncoder::EncodeMaterial(FaceIndex face_id) {
|
||||||
|
int material_id = 0;
|
||||||
|
// Pick the first corner, all corners of a face should have same id.
|
||||||
|
const PointIndex vert_index = in_mesh_->face(face_id)[0];
|
||||||
|
const AttributeValueIndex index_id(material_att_->mapped_index(vert_index));
|
||||||
|
if (!material_att_->ConvertValue<int>(index_id, &material_id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (material_id != current_material_id_) {
|
||||||
|
// Update material information.
|
||||||
|
buffer()->Encode("usemtl ", 7);
|
||||||
|
const auto mat_ptr = material_id_to_name_.find(material_id);
|
||||||
|
// If the material id is not found.
|
||||||
|
if (mat_ptr == material_id_to_name_.end())
|
||||||
|
return false;
|
||||||
|
buffer()->Encode(mat_ptr->second.c_str(), mat_ptr->second.size());
|
||||||
|
buffer()->Encode("\n", 1);
|
||||||
|
current_material_id_ = material_id;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjEncoder::EncodeSubObject(FaceIndex face_id) {
|
||||||
|
int sub_obj_id = 0;
|
||||||
|
// Pick the first corner, all corners of a face should have same id.
|
||||||
|
const PointIndex vert_index = in_mesh_->face(face_id)[0];
|
||||||
|
const AttributeValueIndex index_id(sub_obj_att_->mapped_index(vert_index));
|
||||||
|
if (!sub_obj_att_->ConvertValue<int>(index_id, &sub_obj_id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (sub_obj_id != current_sub_obj_id_) {
|
||||||
|
buffer()->Encode("o ", 2);
|
||||||
|
const auto sub_obj_ptr = sub_obj_id_to_name_.find(sub_obj_id);
|
||||||
|
if (sub_obj_ptr == sub_obj_id_to_name_.end())
|
||||||
|
return false;
|
||||||
|
buffer()->Encode(sub_obj_ptr->second.c_str(), sub_obj_ptr->second.size());
|
||||||
|
buffer()->Encode("\n", 1);
|
||||||
|
current_sub_obj_id_ = sub_obj_id;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ObjEncoder::EncodeFaceCorner(FaceIndex face_id, int local_corner_id) {
|
bool ObjEncoder::EncodeFaceCorner(FaceIndex face_id, int local_corner_id) {
|
||||||
buffer()->Encode(' ');
|
buffer()->Encode(' ');
|
||||||
const PointIndex vert_index = in_mesh_->face(face_id)[local_corner_id];
|
const PointIndex vert_index = in_mesh_->face(face_id)[local_corner_id];
|
||||||
|
@ -42,10 +42,14 @@ class ObjEncoder {
|
|||||||
bool ExitAndCleanup(bool return_value);
|
bool ExitAndCleanup(bool return_value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool GetSubObjects();
|
||||||
|
bool EncodeMaterialFileName();
|
||||||
bool EncodePositions();
|
bool EncodePositions();
|
||||||
bool EncodeTextureCoordinates();
|
bool EncodeTextureCoordinates();
|
||||||
bool EncodeNormals();
|
bool EncodeNormals();
|
||||||
bool EncodeFaces();
|
bool EncodeFaces();
|
||||||
|
bool EncodeSubObject(FaceIndex face_id);
|
||||||
|
bool EncodeMaterial(FaceIndex face_id);
|
||||||
bool EncodeFaceCorner(FaceIndex face_id, int local_corner_id);
|
bool EncodeFaceCorner(FaceIndex face_id, int local_corner_id);
|
||||||
|
|
||||||
void EncodeFloat(float val);
|
void EncodeFloat(float val);
|
||||||
@ -57,6 +61,8 @@ class ObjEncoder {
|
|||||||
const PointAttribute *pos_att_;
|
const PointAttribute *pos_att_;
|
||||||
const PointAttribute *tex_coord_att_;
|
const PointAttribute *tex_coord_att_;
|
||||||
const PointAttribute *normal_att_;
|
const PointAttribute *normal_att_;
|
||||||
|
const PointAttribute *material_att_;
|
||||||
|
const PointAttribute *sub_obj_att_;
|
||||||
|
|
||||||
// Buffer used for encoding float/int numbers.
|
// Buffer used for encoding float/int numbers.
|
||||||
char num_buffer_[20];
|
char num_buffer_[20];
|
||||||
@ -65,6 +71,16 @@ class ObjEncoder {
|
|||||||
|
|
||||||
const PointCloud *in_point_cloud_;
|
const PointCloud *in_point_cloud_;
|
||||||
const Mesh *in_mesh_;
|
const Mesh *in_mesh_;
|
||||||
|
|
||||||
|
// Store sub object name for each value.
|
||||||
|
std::unordered_map<int, std::string> sub_obj_id_to_name_;
|
||||||
|
// Current sub object id of faces.
|
||||||
|
int current_sub_obj_id_;
|
||||||
|
|
||||||
|
// Store material name for each value in material attribute.
|
||||||
|
std::unordered_map<int, std::string> material_id_to_name_;
|
||||||
|
// Current material id of faces.
|
||||||
|
int current_material_id_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace draco
|
} // namespace draco
|
||||||
|
113
src/draco/io/obj_encoder_test.cc
Normal file
113
src/draco/io/obj_encoder_test.cc
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
// Copyright 2017 The Draco Authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "draco/core/draco_test_base.h"
|
||||||
|
#include "draco/core/draco_test_utils.h"
|
||||||
|
#include "draco/io/obj_decoder.h"
|
||||||
|
#include "draco/io/obj_encoder.h"
|
||||||
|
|
||||||
|
namespace draco {
|
||||||
|
|
||||||
|
class ObjEncoderTest : public ::testing::Test {
|
||||||
|
protected:
|
||||||
|
template <class Geometry>
|
||||||
|
std::unique_ptr<Mesh> DecodeFromObjFile(const std::string &file_name) const {
|
||||||
|
const std::string path = GetTestFileFullPath(file_name);
|
||||||
|
std::unique_ptr<Mesh> mesh(new Mesh());
|
||||||
|
ObjDecoder decoder;
|
||||||
|
decoder.set_use_metadata(true);
|
||||||
|
if (!decoder.DecodeFromFile(path, mesh.get()))
|
||||||
|
return nullptr;
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompareMeshes(const Mesh *mesh0, const Mesh *mesh1) {
|
||||||
|
ASSERT_EQ(mesh0->num_faces(), mesh1->num_faces());
|
||||||
|
ASSERT_EQ(mesh0->num_attributes(), mesh1->num_attributes());
|
||||||
|
for (size_t att_id = 0; att_id < mesh0->num_attributes(); ++att_id) {
|
||||||
|
ASSERT_EQ(mesh0->attribute(att_id)->size(),
|
||||||
|
mesh1->attribute(att_id)->size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode a mesh using the ObjEncoder and then decode to verify the encoding.
|
||||||
|
std::unique_ptr<Mesh> EncodeAndDecodeMesh(const Mesh *mesh) {
|
||||||
|
EncoderBuffer encoder_buffer;
|
||||||
|
ObjEncoder encoder;
|
||||||
|
if (!encoder.EncodeToBuffer(*mesh, &encoder_buffer))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
DecoderBuffer decoder_buffer;
|
||||||
|
decoder_buffer.Init(encoder_buffer.data(), encoder_buffer.size());
|
||||||
|
std::unique_ptr<Mesh> decoded_mesh(new Mesh());
|
||||||
|
ObjDecoder decoder;
|
||||||
|
decoder.set_use_metadata(true);
|
||||||
|
if (!decoder.DecodeFromBuffer(&decoder_buffer, decoded_mesh.get()))
|
||||||
|
return nullptr;
|
||||||
|
return decoded_mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_encoding(const std::string &file_name) {
|
||||||
|
const std::unique_ptr<Mesh> mesh(DecodeFromObjFile<Mesh>(file_name));
|
||||||
|
|
||||||
|
ASSERT_NE(mesh, nullptr) << "Failed to load test model " << file_name;
|
||||||
|
ASSERT_GT(mesh->num_faces(), 0);
|
||||||
|
|
||||||
|
const std::unique_ptr<Mesh> decoded_mesh = EncodeAndDecodeMesh(mesh.get());
|
||||||
|
CompareMeshes(mesh.get(), decoded_mesh.get());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(ObjEncoderTest, HasSubObject) { test_encoding("cube_att_sub_o.obj"); }
|
||||||
|
|
||||||
|
TEST_F(ObjEncoderTest, HasMaterial) {
|
||||||
|
const std::unique_ptr<Mesh> mesh0(DecodeFromObjFile<Mesh>("mat_test.obj"));
|
||||||
|
ASSERT_NE(mesh0, nullptr);
|
||||||
|
const std::unique_ptr<Mesh> mesh1 = EncodeAndDecodeMesh(mesh0.get());
|
||||||
|
ASSERT_NE(mesh1, nullptr);
|
||||||
|
ASSERT_EQ(mesh0->num_faces(), mesh1->num_faces());
|
||||||
|
ASSERT_EQ(mesh0->num_attributes(), mesh1->num_attributes());
|
||||||
|
// Position attribute should be the same.
|
||||||
|
ASSERT_EQ(mesh0->attribute(0)->size(), mesh1->attribute(0)->size());
|
||||||
|
// Since |mesh1| is decoded from buffer, it has not material file. So the
|
||||||
|
// size of material attribute is the number of materials used in the obj
|
||||||
|
// file which is 6. The size of material attribute of |mesh0| decoded from
|
||||||
|
// the obj file will be the number of materials defined in the .mtl file.
|
||||||
|
ASSERT_EQ(mesh0->attribute(1)->size(), 29);
|
||||||
|
ASSERT_EQ(mesh1->attribute(1)->size(), 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ObjEncoderTest, TestObjEncodingAll) {
|
||||||
|
// Test decoded mesh from encoded obj file stays the same.
|
||||||
|
test_encoding("bunny_norm.obj");
|
||||||
|
test_encoding("cube_att.obj");
|
||||||
|
test_encoding("cube_att_partial.obj");
|
||||||
|
test_encoding("cube_quads.obj");
|
||||||
|
test_encoding("cube_subd.obj");
|
||||||
|
test_encoding("extra_vertex.obj");
|
||||||
|
test_encoding("one_face_123.obj");
|
||||||
|
test_encoding("one_face_312.obj");
|
||||||
|
test_encoding("one_face_321.obj");
|
||||||
|
test_encoding("sphere.obj");
|
||||||
|
test_encoding("test_nm.obj");
|
||||||
|
test_encoding("test_nm_trans.obj");
|
||||||
|
test_encoding("test_sphere.obj");
|
||||||
|
test_encoding("three_faces_123.obj");
|
||||||
|
test_encoding("three_faces_312.obj");
|
||||||
|
test_encoding("two_faces_123.obj");
|
||||||
|
test_encoding("two_faces_312.obj");
|
||||||
|
}
|
||||||
|
} // namespace draco
|
@ -129,6 +129,11 @@ const PointAttribute *Decoder::GetAttribute(const PointCloud &pc, long att_id) {
|
|||||||
return pc.attribute(att_id);
|
return pc.attribute(att_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PointAttribute *Decoder::GetAttributeByUniqueId(const PointCloud &pc,
|
||||||
|
long unique_id) {
|
||||||
|
return pc.GetAttributeByUniqueId(unique_id);
|
||||||
|
}
|
||||||
|
|
||||||
long Decoder::GetAttributeIdByName(const PointCloud &pc,
|
long Decoder::GetAttributeIdByName(const PointCloud &pc,
|
||||||
const char *attribute_name) {
|
const char *attribute_name) {
|
||||||
const std::string entry_value(attribute_name);
|
const std::string entry_value(attribute_name);
|
||||||
|
@ -120,6 +120,10 @@ class Decoder {
|
|||||||
const char *metadata_name,
|
const char *metadata_name,
|
||||||
const char *metadata_value);
|
const char *metadata_value);
|
||||||
|
|
||||||
|
// Returns an attribute id of an attribute that has the unqiue id.
|
||||||
|
static const draco::PointAttribute *GetAttributeByUniqueId(
|
||||||
|
const draco::PointCloud &pc, long unique_id);
|
||||||
|
|
||||||
// Returns a PointAttribute pointer from |att_id| index.
|
// Returns a PointAttribute pointer from |att_id| index.
|
||||||
static const draco::PointAttribute *GetAttribute(const draco::PointCloud &pc,
|
static const draco::PointAttribute *GetAttribute(const draco::PointCloud &pc,
|
||||||
long att_id);
|
long att_id);
|
||||||
|
@ -158,6 +158,8 @@ interface Decoder {
|
|||||||
[Const] DOMString value);
|
[Const] DOMString value);
|
||||||
|
|
||||||
[Const] PointAttribute GetAttribute([Ref, Const] PointCloud pc, long att_id);
|
[Const] PointAttribute GetAttribute([Ref, Const] PointCloud pc, long att_id);
|
||||||
|
[Const] PointAttribute GetAttributeByUniqueId([Ref, Const] PointCloud pc,
|
||||||
|
long unique_id);
|
||||||
|
|
||||||
[Const] Metadata GetMetadata([Ref, Const] PointCloud pc);
|
[Const] Metadata GetMetadata([Ref, Const] PointCloud pc);
|
||||||
[Const] Metadata GetAttributeMetadata([Ref, Const] PointCloud pc,
|
[Const] Metadata GetAttributeMetadata([Ref, Const] PointCloud pc,
|
||||||
|
@ -19,7 +19,7 @@ function isVersionSupported(versionString) {
|
|||||||
const version = versionString.split('.');
|
const version = versionString.split('.');
|
||||||
if (version.length < 2 || version.length > 3)
|
if (version.length < 2 || version.length > 3)
|
||||||
return false; // Unexpected version string.
|
return false; // Unexpected version string.
|
||||||
if (version[0] == 1 && version[1] == 0)
|
if (version[0] == 1 && version[1] >= 0 && version[1] <= 1)
|
||||||
return true;
|
return true;
|
||||||
if (version[0] != 0 || version[1] > 10)
|
if (version[0] != 0 || version[1] > 10)
|
||||||
return false;
|
return false;
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
#include "draco/mesh/corner_table.h"
|
#include "draco/mesh/corner_table.h"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
#include "draco/mesh/corner_table_iterators.h"
|
#include "draco/mesh/corner_table_iterators.h"
|
||||||
|
|
||||||
namespace draco {
|
namespace draco {
|
||||||
@ -49,6 +52,8 @@ bool CornerTable::Initialize(
|
|||||||
bool CornerTable::Reset(int num_faces) {
|
bool CornerTable::Reset(int num_faces) {
|
||||||
if (num_faces < 0)
|
if (num_faces < 0)
|
||||||
return false;
|
return false;
|
||||||
|
if (num_faces > std::numeric_limits<CornerIndex::ValueType>::max() / 3)
|
||||||
|
return false;
|
||||||
corner_to_vertex_map_.assign(num_faces * 3, kInvalidVertexIndex);
|
corner_to_vertex_map_.assign(num_faces * 3, kInvalidVertexIndex);
|
||||||
opposite_corners_.assign(num_faces * 3, kInvalidCornerIndex);
|
opposite_corners_.assign(num_faces * 3, kInvalidCornerIndex);
|
||||||
vertex_corners_.reserve(num_faces * 3);
|
vertex_corners_.reserve(num_faces * 3);
|
||||||
|
@ -37,6 +37,23 @@ std::unique_ptr<CornerTable> CreateCornerTable(const Mesh *mesh) {
|
|||||||
return CT::Create(faces);
|
return CT::Create(faces);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<CornerTable> CreateCornerTableFromAllAttributes(
|
||||||
|
const Mesh *mesh) {
|
||||||
|
IndexTypeVector<FaceIndex, FaceType> faces(mesh->num_faces());
|
||||||
|
FaceType new_face;
|
||||||
|
for (FaceIndex i(0); i < mesh->num_faces(); ++i) {
|
||||||
|
const Mesh::Face &face = mesh->face(i);
|
||||||
|
// Each face is identified by point indices that automatically split the
|
||||||
|
// mesh along attribute seams.
|
||||||
|
for (int j = 0; j < 3; ++j) {
|
||||||
|
new_face[j] = face[j].value();
|
||||||
|
}
|
||||||
|
faces[i] = new_face;
|
||||||
|
}
|
||||||
|
// Build the corner table.
|
||||||
|
return CornerTable::Create(faces);
|
||||||
|
}
|
||||||
|
|
||||||
PointIndex CornerToPointId(CornerIndex ci, const CornerTable *ct,
|
PointIndex CornerToPointId(CornerIndex ci, const CornerTable *ct,
|
||||||
const Mesh *mesh) {
|
const Mesh *mesh) {
|
||||||
if (!ct->IsValid(ci))
|
if (!ct->IsValid(ci))
|
||||||
|
@ -23,9 +23,15 @@
|
|||||||
|
|
||||||
namespace draco {
|
namespace draco {
|
||||||
|
|
||||||
// Creates a CornerTable from |*mesh|. Returns nullptr on error.
|
// Creates a CornerTable from the position attribute of |mesh|. Returns nullptr
|
||||||
|
// on error.
|
||||||
std::unique_ptr<CornerTable> CreateCornerTable(const Mesh *mesh);
|
std::unique_ptr<CornerTable> CreateCornerTable(const Mesh *mesh);
|
||||||
|
|
||||||
|
// Creates a CornerTable from all attributes of |mesh|. Boundaries are
|
||||||
|
// automatically introduced on all attribute seams. Returns nullptr on error.
|
||||||
|
std::unique_ptr<CornerTable> CreateCornerTableFromAllAttributes(
|
||||||
|
const Mesh *mesh);
|
||||||
|
|
||||||
// Returns the point id stored on corner |ci|.
|
// Returns the point id stored on corner |ci|.
|
||||||
PointIndex CornerToPointId(CornerIndex ci, const CornerTable *ct,
|
PointIndex CornerToPointId(CornerIndex ci, const CornerTable *ct,
|
||||||
const Mesh *mesh);
|
const Mesh *mesh);
|
||||||
|
@ -63,6 +63,14 @@ const PointAttribute *PointCloud::GetNamedAttributeByUniqueId(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PointAttribute *PointCloud::GetAttributeByUniqueId(uint32_t id) const {
|
||||||
|
for (size_t att_id = 0; att_id < attributes_.size(); ++att_id) {
|
||||||
|
if (attributes_[att_id]->unique_id() == id)
|
||||||
|
return attributes_[att_id].get();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
int PointCloud::AddAttribute(std::unique_ptr<PointAttribute> pa) {
|
int PointCloud::AddAttribute(std::unique_ptr<PointAttribute> pa) {
|
||||||
SetAttribute(attributes_.size(), std::move(pa));
|
SetAttribute(attributes_.size(), std::move(pa));
|
||||||
return attributes_.size() - 1;
|
return attributes_.size() - 1;
|
||||||
|
@ -50,6 +50,9 @@ class PointCloud {
|
|||||||
const PointAttribute *GetNamedAttributeByUniqueId(
|
const PointAttribute *GetNamedAttributeByUniqueId(
|
||||||
GeometryAttribute::Type type, uint32_t id) const;
|
GeometryAttribute::Type type, uint32_t id) const;
|
||||||
|
|
||||||
|
// Returns the attribute of a given unique id.
|
||||||
|
const PointAttribute *GetAttributeByUniqueId(uint32_t id) const;
|
||||||
|
|
||||||
int32_t num_attributes() const { return attributes_.size(); }
|
int32_t num_attributes() const { return attributes_.size(); }
|
||||||
const PointAttribute *attribute(int32_t att_id) const {
|
const PointAttribute *attribute(int32_t att_id) const {
|
||||||
DCHECK_LE(0, att_id);
|
DCHECK_LE(0, att_id);
|
||||||
|
@ -32,6 +32,8 @@ struct Options {
|
|||||||
bool tex_coords_deleted;
|
bool tex_coords_deleted;
|
||||||
int normals_quantization_bits;
|
int normals_quantization_bits;
|
||||||
bool normals_deleted;
|
bool normals_deleted;
|
||||||
|
int generic_quantization_bits;
|
||||||
|
bool generic_deleted;
|
||||||
int compression_level;
|
int compression_level;
|
||||||
bool use_metadata;
|
bool use_metadata;
|
||||||
std::string input;
|
std::string input;
|
||||||
@ -45,6 +47,8 @@ Options::Options()
|
|||||||
tex_coords_deleted(false),
|
tex_coords_deleted(false),
|
||||||
normals_quantization_bits(10),
|
normals_quantization_bits(10),
|
||||||
normals_deleted(false),
|
normals_deleted(false),
|
||||||
|
generic_quantization_bits(8),
|
||||||
|
generic_deleted(false),
|
||||||
compression_level(7) {}
|
compression_level(7) {}
|
||||||
|
|
||||||
void Usage() {
|
void Usage() {
|
||||||
@ -66,11 +70,15 @@ void Usage() {
|
|||||||
printf(
|
printf(
|
||||||
" -qn <value> quantization bits for the normal vector "
|
" -qn <value> quantization bits for the normal vector "
|
||||||
"attribute, default=10.\n");
|
"attribute, default=10.\n");
|
||||||
|
printf(
|
||||||
|
" -qg <value> quantization bits for any generic attribute, "
|
||||||
|
"default=8.\n");
|
||||||
printf(
|
printf(
|
||||||
" -cl <value> compression level [0-10], most=10, least=0, "
|
" -cl <value> compression level [0-10], most=10, least=0, "
|
||||||
"default=7.\n");
|
"default=7.\n");
|
||||||
printf(
|
printf(
|
||||||
" --skip ATTRIBUTE_NAME skip a given attribute (NORMAL, TEX_COORD)\n");
|
" --skip ATTRIBUTE_NAME skip a given attribute (NORMAL, TEX_COORD, "
|
||||||
|
"GENERIC)\n");
|
||||||
printf(
|
printf(
|
||||||
"\nUse negative quantization values to skip the specified attribute\n");
|
"\nUse negative quantization values to skip the specified attribute\n");
|
||||||
printf(
|
printf(
|
||||||
@ -114,6 +122,17 @@ void PrintOptions(const draco::PointCloud &pc, const Options &options) {
|
|||||||
} else if (options.normals_deleted) {
|
} else if (options.normals_deleted) {
|
||||||
printf(" Normals: Skipped\n");
|
printf(" Normals: Skipped\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pc.GetNamedAttributeId(draco::GeometryAttribute::GENERIC) >= 0) {
|
||||||
|
if (options.generic_quantization_bits == 0) {
|
||||||
|
printf(" Generic: No quantization\n");
|
||||||
|
} else {
|
||||||
|
printf(" Generic: Quantization = %d bits\n",
|
||||||
|
options.generic_quantization_bits);
|
||||||
|
}
|
||||||
|
} else if (options.generic_deleted) {
|
||||||
|
printf(" Generic: Skipped\n");
|
||||||
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,6 +228,14 @@ int main(int argc, char **argv) {
|
|||||||
"attribute is 31.\n");
|
"attribute is 31.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
} else if (!strcmp("-qg", argv[i]) && i < argc_check) {
|
||||||
|
options.generic_quantization_bits = StringToInt(argv[++i]);
|
||||||
|
if (options.generic_quantization_bits > 31) {
|
||||||
|
printf(
|
||||||
|
"Error: The maximum number of quantization bits for generic "
|
||||||
|
"attributes is 31.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
} else if (!strcmp("-cl", argv[i]) && i < argc_check) {
|
} else if (!strcmp("-cl", argv[i]) && i < argc_check) {
|
||||||
options.compression_level = StringToInt(argv[++i]);
|
options.compression_level = StringToInt(argv[++i]);
|
||||||
} else if (!strcmp("--skip", argv[i]) && i < argc_check) {
|
} else if (!strcmp("--skip", argv[i]) && i < argc_check) {
|
||||||
@ -216,11 +243,14 @@ int main(int argc, char **argv) {
|
|||||||
options.normals_quantization_bits = -1;
|
options.normals_quantization_bits = -1;
|
||||||
} else if (!strcmp("TEX_COORD", argv[i + 1])) {
|
} else if (!strcmp("TEX_COORD", argv[i + 1])) {
|
||||||
options.tex_coords_quantization_bits = -1;
|
options.tex_coords_quantization_bits = -1;
|
||||||
|
} else if (!strcmp("GENERIC", argv[i + 1])) {
|
||||||
|
options.generic_quantization_bits = -1;
|
||||||
} else {
|
} else {
|
||||||
printf("Error: Invalid attribute name after --skip\n");
|
printf("Error: Invalid attribute name after --skip\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else if (!strcmp("--metadata", argv[i]) && i < argc_check) {
|
++i;
|
||||||
|
} else if (!strcmp("--metadata", argv[i])) {
|
||||||
options.use_metadata = true;
|
options.use_metadata = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -273,10 +303,19 @@ int main(int argc, char **argv) {
|
|||||||
pc->GetNamedAttributeId(draco::GeometryAttribute::NORMAL, 0));
|
pc->GetNamedAttributeId(draco::GeometryAttribute::NORMAL, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (options.generic_quantization_bits < 0) {
|
||||||
|
if (pc->NumNamedAttributes(draco::GeometryAttribute::GENERIC) > 0) {
|
||||||
|
options.generic_deleted = true;
|
||||||
|
}
|
||||||
|
while (pc->NumNamedAttributes(draco::GeometryAttribute::GENERIC) > 0) {
|
||||||
|
pc->DeleteAttribute(
|
||||||
|
pc->GetNamedAttributeId(draco::GeometryAttribute::GENERIC, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
// If any attribute has been deleted, run deduplication of point indices again
|
// If any attribute has been deleted, run deduplication of point indices again
|
||||||
// as some points can be possibly combined.
|
// as some points can be possibly combined.
|
||||||
if (options.tex_coords_deleted || options.normals_deleted) {
|
if (options.tex_coords_deleted || options.normals_deleted ||
|
||||||
|
options.generic_deleted) {
|
||||||
pc->DeduplicatePointIds();
|
pc->DeduplicatePointIds();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,6 +336,10 @@ int main(int argc, char **argv) {
|
|||||||
encoder.SetAttributeQuantization(draco::GeometryAttribute::NORMAL,
|
encoder.SetAttributeQuantization(draco::GeometryAttribute::NORMAL,
|
||||||
options.normals_quantization_bits);
|
options.normals_quantization_bits);
|
||||||
}
|
}
|
||||||
|
if (options.generic_quantization_bits > 0) {
|
||||||
|
encoder.SetAttributeQuantization(draco::GeometryAttribute::GENERIC,
|
||||||
|
options.generic_quantization_bits);
|
||||||
|
}
|
||||||
encoder.SetSpeedOptions(speed, speed);
|
encoder.SetSpeedOptions(speed, speed);
|
||||||
|
|
||||||
if (options.output.empty()) {
|
if (options.output.empty()) {
|
||||||
|
1
testdata/mat_test.obj
vendored
1
testdata/mat_test.obj
vendored
@ -4878,6 +4878,7 @@ f 2125 2124 2126
|
|||||||
f 2128 2127 2130
|
f 2128 2127 2130
|
||||||
f 2129 2128 2130
|
f 2129 2128 2130
|
||||||
f 2132 2131 2136
|
f 2132 2131 2136
|
||||||
|
usemtl unknown_mat_in_mtl_file
|
||||||
f 2133 2132 2136
|
f 2133 2132 2136
|
||||||
f 2134 2133 2136
|
f 2134 2133 2136
|
||||||
f 2135 2134 2136
|
f 2135 2134 2136
|
||||||
|
BIN
testdata/test_nm.obj.edgebreaker.1.1.0.drc
vendored
Normal file
BIN
testdata/test_nm.obj.edgebreaker.1.1.0.drc
vendored
Normal file
Binary file not shown.
BIN
testdata/test_nm.obj.sequential.1.1.0.drc
vendored
Normal file
BIN
testdata/test_nm.obj.sequential.1.1.0.drc
vendored
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user