Natha1627 commited on
Commit
3b6bb5e
·
1 Parent(s): c6f625c

Initial commit

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .env +1 -0
  2. .history/.env_20241115180340 +1 -0
  3. .history/.env_20241204120505 +1 -0
  4. .history/.env_20241204120506 +1 -0
  5. .history/.env_20241204120509 +1 -0
  6. .history/.env_20241204120512 +1 -0
  7. .history/.env_20241204120522 +1 -0
  8. .history/.env_20241204120639 +1 -0
  9. .history/Dockerfile_20241204120405 +0 -0
  10. .history/Dockerfile_20241204120409 +29 -0
  11. .history/Dockerfile_20241204120738 +29 -0
  12. .history/Dockerfile_20241204120940 +29 -0
  13. .history/Dockerfile_20241204121832 +29 -0
  14. .history/combined.min_20241119235702.js +1 -0
  15. .history/combined.min_20241120000008.js +3 -0
  16. .history/combined.min_20241120000010.js +2 -0
  17. .history/combined_20241201141501.js +0 -0
  18. .history/combined_20241201141504.js +0 -0
  19. .history/copyslices.worker_20241118132102.js +129 -0
  20. .history/copyslices.worker_20241204081957.js +129 -0
  21. .history/copyslices.worker_20241204081958.js +129 -0
  22. .history/copyslices.worker_20241204082633.js +129 -0
  23. .history/copyslices.worker_20241204114216.js +129 -0
  24. .history/copyslices.worker_20241204114218.js +129 -0
  25. .history/fetch_ex_bbox_20241120090937.js +0 -0
  26. .history/fetch_ex_bbox_20241120090941.js +108 -0
  27. .history/fetch_ex_bbox_20241120093705.js +133 -0
  28. .history/fetch_ex_bbox_20241120093930.js +136 -0
  29. .history/form/index_20241119001656.html +71 -0
  30. .history/form/index_20241120180531.html +67 -0
  31. .history/form/index_20241120180543.html +66 -0
  32. .history/globals_20241204111341.js +186 -0
  33. .history/globals_20241204114937.js +186 -0
  34. .history/globals_20241204114940.js +186 -0
  35. .history/index_20241118162737.js +549 -0
  36. .history/index_20241119000624.html +132 -0
  37. .history/index_20241119234025.html +129 -0
  38. .history/index_20241119234048.html +100 -0
  39. .history/index_20241119234054.html +95 -0
  40. .history/index_20241119234122.html +95 -0
  41. .history/index_20241119234131.html +90 -0
  42. .history/index_20241119234135.html +90 -0
  43. .history/index_20241119235124.html +47 -0
  44. .history/index_20241119235326.html +90 -0
  45. .history/index_20241119235341.html +71 -0
  46. .history/index_20241119235343.html +71 -0
  47. .history/index_20241119235345.html +71 -0
  48. .history/index_20241119235353.html +71 -0
  49. .history/index_20241119235401.html +71 -0
  50. .history/index_20241120000644.html +199 -0
.env ADDED
@@ -0,0 +1 @@
 
 
1
+ GOOGLE_APPLICATION_CREDENTIALS=service-key.json
.history/.env_20241115180340 ADDED
@@ -0,0 +1 @@
 
 
1
+ GOOGLE_APPLICATION_CREDENTIALS=C:/Users/minin/OneDrive - Université Paris-Dauphine/A1_PROJECT/custom_v14/service-account-key.json
.history/.env_20241204120505 ADDED
@@ -0,0 +1 @@
 
 
1
+ GOOGLE_APPLICATION_CREDENTIALS=app
.history/.env_20241204120506 ADDED
@@ -0,0 +1 @@
 
 
1
+ GOOGLE_APPLICATION_CREDENTIALS=app/
.history/.env_20241204120509 ADDED
@@ -0,0 +1 @@
 
 
1
+ GOOGLE_APPLICATION_CREDENTIALS=app/service
.history/.env_20241204120512 ADDED
@@ -0,0 +1 @@
 
 
1
+ GOOGLE_APPLICATION_CREDENTIALS=app/service-key.json
.history/.env_20241204120522 ADDED
@@ -0,0 +1 @@
 
 
1
+ GOOGLE_APPLICATION_CREDENTIALS=/app/service-key.json
.history/.env_20241204120639 ADDED
@@ -0,0 +1 @@
 
 
1
+ GOOGLE_APPLICATION_CREDENTIALS=service-key.json
.history/Dockerfile_20241204120405 ADDED
File without changes
.history/Dockerfile_20241204120409 ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Utilise l'image officielle de Node.js
2
+ FROM node:18
3
+
4
+ # Définir le répertoire de travail
5
+ WORKDIR /app
6
+
7
+ # Copier le fichier package.json et package-lock.json pour installer les dépendances
8
+ COPY package*.json ./
9
+
10
+ # Copier le fichier de service-key.json dans le conteneur
11
+ COPY service-key.json /app/service-key.json
12
+
13
+ # Copier le fichier .env dans le conteneur
14
+ COPY .env /app/.env
15
+
16
+ # Installer les dépendances
17
+ RUN npm install
18
+
19
+ # Copier le reste de l'application
20
+ COPY . .
21
+
22
+ # Définir la variable d'environnement pour les credentials Google
23
+ ENV GOOGLE_APPLICATION_CREDENTIALS=/app/service-key.json
24
+
25
+ # Exposer le port utilisé par l'application
26
+ EXPOSE 3001
27
+
28
+ # Démarrer le serveur
29
+ CMD ["node", "server.cjs"]
.history/Dockerfile_20241204120738 ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Utilise l'image officielle de Node.js
2
+ FROM node:18
3
+
4
+ # Définir le répertoire de travail
5
+ WORKDIR /app
6
+
7
+ # Copier le fichier package.json et package-lock.json pour installer les dépendances
8
+ COPY package*.json ./
9
+
10
+ # Copier le fichier de service-key.json dans le conteneur
11
+ COPY service-key.json app/service-key.json
12
+
13
+ # Copier le fichier .env dans le conteneur
14
+ COPY .env /app/.env
15
+
16
+ # Installer les dépendances
17
+ RUN npm install
18
+
19
+ # Copier le reste de l'application
20
+ COPY . .
21
+
22
+ # Définir la variable d'environnement pour les credentials Google
23
+ ENV GOOGLE_APPLICATION_CREDENTIALS=/app/service-key.json
24
+
25
+ # Exposer le port utilisé par l'application
26
+ EXPOSE 3001
27
+
28
+ # Démarrer le serveur
29
+ CMD ["node", "server.cjs"]
.history/Dockerfile_20241204120940 ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Utilise l'image officielle de Node.js comme base
2
+ FROM node:18
3
+
4
+ # Définir le répertoire de travail
5
+ WORKDIR /app
6
+
7
+ # Copier package.json et package-lock.json dans le conteneur
8
+ COPY package*.json ./
9
+
10
+ # Installer les dépendances
11
+ RUN npm install
12
+
13
+ # Copier le fichier service-key.json
14
+ COPY service-key.json /app/service-key.json
15
+
16
+ # Copier le fichier .env dans le conteneur
17
+ COPY .env /app/.env
18
+
19
+ # Copier le reste de l'application
20
+ COPY . .
21
+
22
+ # Définir la variable d'environnement pour les credentials Google
23
+ ENV GOOGLE_APPLICATION_CREDENTIALS=/app/service-key.json
24
+
25
+ # Exposer le port utilisé par l'application
26
+ EXPOSE 3001
27
+
28
+ # Démarrer le serveur
29
+ CMD ["node", "server.cjs"]
.history/Dockerfile_20241204121832 ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Utilise l'image officielle de Node.js comme base
2
+ FROM node:18
3
+
4
+ # Définir le répertoire de travail
5
+ WORKDIR /app
6
+
7
+ # Copier package.json et package-lock.json dans le conteneur
8
+ COPY package*.json ./
9
+
10
+ # Installer les dépendances
11
+ RUN npm install
12
+
13
+ # Copier le fichier service-key.json
14
+ COPY service-key.json /app/service-key.json
15
+
16
+ # Copier le fichier .env dans le conteneur
17
+ COPY .env /app/.env
18
+
19
+ # Copier le reste de l'application
20
+ COPY . .
21
+
22
+ # Définir la variable d'environnement pour les credentials Google
23
+ ENV GOOGLE_APPLICATION_CREDENTIALS=/app/service-key.json
24
+
25
+ # Exposer le port utilisé par l'application
26
+ EXPOSE 7860
27
+
28
+ # Démarrer le serveur
29
+ CMD ["node", "server.cjs"]
.history/combined.min_20241119235702.js ADDED
@@ -0,0 +1 @@
 
 
1
+ let DecodeStream=function(){function e(){this.pos=0,this.bufferLength=0,this.eof=!1,this.buffer=null}return e.prototype={ensureBuffer:function(e){var t=this.buffer,r=t?t.byteLength:0;if(e<r)return t;for(var a=512;a<e;)a<<=1;for(var n=new Uint8Array(a),s=0;s<r;++s)n[s]=t[s];return this.buffer=n},getByte:function(){for(var e=this.pos;this.bufferLength<=e;){if(this.eof)return null;this.readBlock()}return this.buffer[this.pos++]},getBytes:function(e){var t=this.pos;if(e){this.ensureBuffer(t+e);for(var r=t+e;!this.eof&&this.bufferLength<r;)this.readBlock();var a=this.bufferLength;r>a&&(r=a)}else{for(;!this.eof;)this.readBlock();r=this.bufferLength}return this.pos=r,this.buffer.subarray(t,r)},lookChar:function(){for(var e=this.pos;this.bufferLength<=e;){if(this.eof)return null;this.readBlock()}return String.fromCharCode(this.buffer[this.pos])},getChar:function(){for(var e=this.pos;this.bufferLength<=e;){if(this.eof)return null;this.readBlock()}return String.fromCharCode(this.buffer[this.pos++])},makeSubStream:function(e,t,r){for(var a=e+t;this.bufferLength<=a&&!this.eof;)this.readBlock();return new Stream(this.buffer,e,t,r)},skip:function(e){e||(e=1),this.pos+=e},reset:function(){this.pos=0}},e}(),FlateStream=function(){var e=new Uint32Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),t=new Uint32Array([3,4,5,6,7,8,9,10,65547,65549,65551,65553,131091,131095,131099,131103,196643,196651,196659,196667,262211,262227,262243,262259,327811,327843,327875,327907,258,258,258]),r=new Uint32Array([1,2,3,4,65541,65543,131081,131085,196625,196633,262177,262193,327745,327777,393345,393409,459009,459137,524801,525057,590849,591361,657409,658433,724993,727041,794625,798721,868353,876545]),a=[new Uint32Array([459008,524368,524304,524568,459024,524400,524336,590016,459016,524384,524320,589984,524288,524416,524352,590048,459012,524376,524312,589968,459028,524408,524344,590032,459020,524392,524328,59e4,524296,524424,524360,590064,459010,524372,524308,524572,459026,524404,524340,590024,459018,524388,524324,589992,524292,524420,524356,590056,459014,524380,524316,589976,459030,524412,524348,590040,459022,524396,524332,590008,524300,524428,524364,590072,459009,524370,524306,524570,459025,524402,524338,590020,459017,524386,524322,589988,524290,524418,524354,590052,459013,524378,524314,589972,459029,524410,524346,590036,459021,524394,524330,590004,524298,524426,524362,590068,459011,524374,524310,524574,459027,524406,524342,590028,459019,524390,524326,589996,524294,524422,524358,590060,459015,524382,524318,589980,459031,524414,524350,590044,459023,524398,524334,590012,524302,524430,524366,590076,459008,524369,524305,524569,459024,524401,524337,590018,459016,524385,524321,589986,524289,524417,524353,590050,459012,524377,524313,589970,459028,524409,524345,590034,459020,524393,524329,590002,524297,524425,524361,590066,459010,524373,524309,524573,459026,524405,524341,590026,459018,524389,524325,589994,524293,524421,524357,590058,459014,524381,524317,589978,459030,524413,524349,590042,459022,524397,524333,590010,524301,524429,524365,590074,459009,524371,524307,524571,459025,524403,524339,590022,459017,524387,524323,589990,524291,524419,524355,590054,459013,524379,524315,589974,459029,524411,524347,590038,459021,524395,524331,590006,524299,524427,524363,590070,459011,524375,524311,524575,459027,524407,524343,590030,459019,524391,524327,589998,524295,524423,524359,590062,459015,524383,524319,589982,459031,524415,524351,590046,459023,524399,524335,590014,524303,524431,524367,590078,459008,524368,524304,524568,459024,524400,524336,590017,459016,524384,524320,589985,524288,524416,524352,590049,459012,524376,524312,589969,459028,524408,524344,590033,459020,524392,524328,590001,524296,524424,524360,590065,459010,524372,524308,524572,459026,524404,524340,590025,459018,524388,524324,589993,524292,524420,524356,590057,459014,524380,524316,589977,459030,524412,524348,590041,459022,524396,524332,590009,524300,524428,524364,590073,459009,524370,524306,524570,459025,524402,524338,590021,459017,524386,524322,589989,524290,524418,524354,590053,459013,524378,524314,589973,459029,524410,524346,590037,459021,524394,524330,590005,524298,524426,524362,590069,459011,524374,524310,524574,459027,524406,524342,590029,459019,524390,524326,589997,524294,524422,524358,590061,459015,524382,524318,589981,459031,524414,524350,590045,459023,524398,524334,590013,524302,524430,524366,590077,459008,524369,524305,524569,459024,524401,524337,590019,459016,524385,524321,589987,524289,524417,524353,590051,459012,524377,524313,589971,459028,524409,524345,590035,459020,524393,524329,590003,524297,524425,524361,590067,459010,524373,524309,524573,459026,524405,524341,590027,459018,524389,524325,589995,524293,524421,524357,590059,459014,524381,524317,589979,459030,524413,524349,590043,459022,524397,524333,590011,524301,524429,524365,590075,459009,524371,524307,524571,459025,524403,524339,590023,459017,524387,524323,589991,524291,524419,524355,590055,459013,524379,524315,589975,459029,524411,524347,590039,459021,524395,524331,590007,524299,524427,524363,590071,459011,524375,524311,524575,459027,524407,524343,590031,459019,524391,524327,589999,524295,524423,524359,590063,459015,524383,524319,589983,459031,524415,524351,590047,459023,524399,524335,590015,524303,524431,524367,590079]),9],n=[new Uint32Array([327680,327696,327688,327704,327684,327700,327692,327708,327682,327698,327690,327706,327686,327702,327694,0,327681,327697,327689,327705,327685,327701,327693,327709,327683,327699,327691,327707,327687,327703,327695,0]),5];function s(e){throw new Error(e)}function i(e){var t=0,r=e[t++],a=e[t++];-1!=r&&-1!=a||s("Invalid header in flate stream"),8!=(15&r)&&s("Unknown compression method in flate stream"),((r<<8)+a)%31!=0&&s("Bad FCHECK in flate stream"),32&a&&s("FDICT bit set in flate stream"),this.bytes=e,this.bytesPos=2,this.codeSize=0,this.codeBuf=0,DecodeStream.call(this)}return i.prototype=Object.create(DecodeStream.prototype),i.prototype.getBits=function(e){for(var t,r=this.codeSize,a=this.codeBuf,n=this.bytes,i=this.bytesPos;r<e;)void 0===(t=n[i++])&&s("Bad encoding in flate stream"),a|=t<<r,r+=8;return t=a&(1<<e)-1,this.codeBuf=a>>e,this.codeSize=r-=e,this.bytesPos=i,t},i.prototype.getCode=function(e){for(var t=e[0],r=e[1],a=this.codeSize,n=this.codeBuf,i=this.bytes,o=this.bytesPos;a<r;){var l;void 0===(l=i[o++])&&s("Bad encoding in flate stream"),n|=l<<a,a+=8}var c=t[n&(1<<r)-1],u=c>>16,d=65535&c;return(0==a||a<u||0==u)&&s("Bad encoding in flate stream"),this.codeBuf=n>>u,this.codeSize=a-u,this.bytesPos=o,d},i.prototype.generateHuffmanTable=function(e){for(var t=e.length,r=0,a=0;a<t;++a)e[a]>r&&(r=e[a]);for(var n=1<<r,s=new Uint32Array(n),i=1,o=0,l=2;i<=r;++i,o<<=1,l<<=1)for(var c=0;c<t;++c)if(e[c]==i){var u=0,d=o;for(a=0;a<i;++a)u=u<<1|1&d,d>>=1;for(a=u;a<n;a+=l)s[a]=i<<16|c;++o}return[s,r]},i.prototype.readBlock=function(){function i(e,t,r,a,n){for(var s=e.getBits(r)+a;s-- >0;)t[m++]=n}var o=this.getBits(3);if(1&o&&(this.eof=!0),0!=(o>>=1)){var l,c;if(1==o)l=a,c=n;else if(2==o){for(var u=this.getBits(5)+257,d=this.getBits(5)+1,p=this.getBits(4)+4,g=Array(e.length),m=0;m<p;)g[e[m++]]=this.getBits(3);for(var h=this.generateHuffmanTable(g),f=0,y=(m=0,u+d),_=new Array(y);m<y;){var T=this.getCode(h);16==T?i(this,_,2,3,f):17==T?i(this,_,3,3,f=0):18==T?i(this,_,7,11,f=0):_[m++]=f=T}l=this.generateHuffmanTable(_.slice(0,u)),c=this.generateHuffmanTable(_.slice(u,y))}else s("Unknown block type in flate stream");for(var x=(M=this.buffer)?M.length:0,S=this.bufferLength;;){var R=this.getCode(l);if(R<256)S+1>=x&&(x=(M=this.ensureBuffer(S+1)).length),M[S++]=R;else{if(256==R)return void(this.bufferLength=S);var E=(R=t[R-=257])>>16;E>0&&(E=this.getBits(E));f=(65535&R)+E;R=this.getCode(c),(E=(R=r[R])>>16)>0&&(E=this.getBits(E));var b=(65535&R)+E;S+f>=x&&(x=(M=this.ensureBuffer(S+f)).length);for(var C=0;C<f;++C,++S)M[S]=M[S-b]}}}else{var w,A=this.bytes,v=this.bytesPos;void 0===(w=A[v++])&&s("Bad block header in flate stream");var G=w;void 0===(w=A[v++])&&s("Bad block header in flate stream"),G|=w<<8,void 0===(w=A[v++])&&s("Bad block header in flate stream");var P=w;void 0===(w=A[v++])&&s("Bad block header in flate stream"),(P|=w<<8)!=(65535&~G)&&s("Bad uncompressed block length in flate stream"),this.codeBuf=0,this.codeSize=0;var D=this.bufferLength,M=this.ensureBuffer(D+G),k=D+G;this.bufferLength=k;for(var F=D;F<k;++F){if(void 0===(w=A[v++])){this.eof=!0;break}M[F]=w}this.bytesPos=v}},i}(),PNG=function(){class e{static load(t,r,a){"function"==typeof r&&(a=r);const n=new XMLHttpRequest;return n.open("GET",t,!0),n.responseType="arraybuffer",n.onload=()=>{const t=new Uint8Array(n.response||n.mozResponseArrayBuffer),s=new e(t);return"function"==typeof(r&&r.getContext)&&s.render(r),"function"==typeof a?a(s):void 0},n.send(null)}constructor(e){let t;this.data=e,this.pos=8,this.palette=[],this.imgData=[],this.transparency={},this.animation=null,this.text={};let r=null;for(;;){var a;let e=this.readUInt32(),d="";for(t=0;t<4;t++)d+=String.fromCharCode(this.data[this.pos++]);switch(d){case"IHDR":this.width=this.readUInt32(),this.height=this.readUInt32(),this.bits=this.data[this.pos++],this.colorType=this.data[this.pos++],this.compressionMethod=this.data[this.pos++],this.filterMethod=this.data[this.pos++],this.interlaceMethod=this.data[this.pos++];break;case"acTL":this.animation={numFrames:this.readUInt32(),numPlays:this.readUInt32()||1/0,frames:[]};break;case"PLTE":this.palette=this.read(e);break;case"fcTL":r&&this.animation.frames.push(r),this.pos+=4,r={width:this.readUInt32(),height:this.readUInt32(),xOffset:this.readUInt32(),yOffset:this.readUInt32()};var n=this.readUInt16(),s=this.readUInt16()||100;r.delay=1e3*n/s,r.disposeOp=this.data[this.pos++],r.blendOp=this.data[this.pos++],r.data=[];break;case"IDAT":case"fdAT":for("fdAT"===d&&(this.pos+=4,e-=4),a=r&&r.data||this.imgData,t=0;t<e;t++)a.push(this.data[this.pos++]);break;case"tRNS":switch(this.transparency={},this.colorType){case 3:this.transparency.indexed=this.read(e);var i=255-this.transparency.indexed.length;if(i>0)for(t=0;t<i;t++)this.transparency.indexed.push(255);break;case 0:this.transparency.grayscale=this.read(e)[0];break;case 2:this.transparency.rgb=this.read(e)}break;case"tEXt":var o=this.read(e),l=o.indexOf(0),c=String.fromCharCode.apply(String,o.slice(0,l));this.text[c]=String.fromCharCode.apply(String,o.slice(l+1));break;case"IEND":switch(r&&this.animation.frames.push(r),this.colorType){case 0:case 3:case 4:this.colors=1;break;case 2:case 6:this.colors=3}this.hasAlphaChannel=[4,6].includes(this.colorType);var u=this.colors+(this.hasAlphaChannel?1:0);switch(this.pixelBitlength=this.bits*u,this.colors){case 1:this.colorSpace="DeviceGray";break;case 3:this.colorSpace="DeviceRGB"}return void(this.imgData=new Uint8Array(this.imgData));default:this.pos+=e}if(this.pos+=4,this.pos>this.data.length)throw new Error("Incomplete or corrupt PNG file")}}read(e){const t=new Array(e);for(let r=0;r<e;r++)t[r]=this.data[this.pos++];return t}readUInt32(){return this.data[this.pos++]<<24|this.data[this.pos++]<<16|this.data[this.pos++]<<8|this.data[this.pos++]}readUInt16(){return this.data[this.pos++]<<8|this.data[this.pos++]}decodePixels(e){if(null==e&&(e=this.imgData),0===e.length)return new Uint8Array(0);e=(e=new FlateStream(e)).getBytes();const{width:t,height:r}=this,a=this.pixelBitlength/8,n=new Uint8Array(t*r*a),{length:s}=e;let i=0;function o(o,l,c,u,d=!1){const p=Math.ceil((t-o)/c),g=Math.ceil((r-l)/u),m=a*p,h=d?n:new Uint8Array(m*g);let f=0,y=0;for(;f<g&&i<s;){var _,T,x,S,R;switch(e[i++]){case 0:for(x=0;x<m;x++)h[y++]=e[i++];break;case 1:for(x=0;x<m;x++)_=e[i++],S=x<a?0:h[y-a],h[y++]=(_+S)%256;break;case 2:for(x=0;x<m;x++)_=e[i++],T=(x-x%a)/a,R=f&&h[(f-1)*m+T*a+x%a],h[y++]=(R+_)%256;break;case 3:for(x=0;x<m;x++)_=e[i++],T=(x-x%a)/a,S=x<a?0:h[y-a],R=f&&h[(f-1)*m+T*a+x%a],h[y++]=(_+Math.floor((S+R)/2))%256;break;case 4:for(x=0;x<m;x++){var E,b;_=e[i++],T=(x-x%a)/a,S=x<a?0:h[y-a],0===f?R=b=0:(R=h[(f-1)*m+T*a+x%a],b=T&&h[(f-1)*m+(T-1)*a+x%a]);const t=S+R-b,r=Math.abs(t-S),n=Math.abs(t-R),s=Math.abs(t-b);E=r<=n&&r<=s?S:n<=s?R:b,h[y++]=(_+E)%256}break;default:throw new Error(`Invalid filter algorithm: ${e[i-1]}`)}if(!d){let e=((l+f*u)*t+o)*a,r=f*m;for(x=0;x<p;x++){for(let t=0;t<a;t++)n[e++]=h[r++];e+=(c-1)*a}}f++}}return 1===this.interlaceMethod?(o(0,0,8,8),o(4,0,8,8),o(0,4,4,8),o(2,0,4,4),o(0,2,2,4),o(1,0,2,2),o(0,1,1,2)):o(0,0,1,1,!0),n}decodePalette(){const{palette:e}=this,{length:t}=e,r=this.transparency.indexed||[],a=new Uint8Array((r.length||0)+t);let n=0,s=0;for(let o=0;o<t;o+=3){var i;a[n++]=e[o],a[n++]=e[o+1],a[n++]=e[o+2],a[n++]=null!=(i=r[s++])?i:255}return a}copyToImageData(e,t){let r,a,{colors:n}=this,s=null,i=this.hasAlphaChannel;this.palette.length&&(s=this._decodedPalette||(this._decodedPalette=this.decodePalette()),n=4,i=!0);const o=e.data||e,{length:l}=o,c=s||t;let u=r=0;if(1===n)for(;u<l;){a=s?4*t[u/4]:r;const e=c[a++];o[u++]=e,o[u++]=e,o[u++]=e,o[u++]=i?c[a++]:255,r=a}else for(;u<l;)a=s?4*t[u/4]:r,o[u++]=c[a++],o[u++]=c[a++],o[u++]=c[a++],o[u++]=i?c[a++]:255,r=a}decode(){const e=new Uint8Array(this.width*this.height*4);return this.copyToImageData(e,this.decodePixels()),e}renderFrame(e,t){const{frames:r}=this.animation,a=r[t],n=r[t-1];return 0===t&&e.clearRect(0,0,this.width,this.height),1===(n&&n.disposeOp)?e.clearRect(n.xOffset,n.yOffset,n.width,n.height):2===(n&&n.disposeOp)&&e.putImageData(n.imageData,n.xOffset,n.yOffset),0===a.blendOp&&e.clearRect(a.xOffset,a.yOffset,a.width,a.height),e.drawImage(a.image,a.xOffset,a.yOffset)}animate(e){let t=0;const{numFrames:r,frames:a,numPlays:n}=this.animation,s=()=>{const i=t++%r,o=a[i];this.renderFrame(e,i),r>1&&t/r<n&&(this.animation._timeout=setTimeout(s,o.delay))};s()}stopAnimation(){return clearTimeout(this.animation&&this.animation._timeout)}render(e){e._png&&e._png.stopAnimation(),e._png=this,e.width=this.width,e.height=this.height;const t=e.getContext("2d");if(this.animation)return this.decodeFrames(t),this.animate(t);{const e=t.createImageData(this.width,this.height);return this.copyToImageData(e,this.decodePixels()),t.putImageData(e,0,0)}}}return e}();function createSceneSpec(e){return{assetType:"scene",occupancyGridsSpec:createOccupancyGridsSpec(e),distanceGridsSpec:createDistanceGridsSpec(e),triplaneSpec:createTriplaneSpec(e),sparseGridSpec:createSparseGridSpec(e)}}function createOccupancyGridsSpec(e){let t=[8,16,32,64,128];return e.useBits&&(t=[8,32,128]),e.useDistanceGrid&&(t=[8]),{assetType:"occupancy_grids",gridSpecs:t.map((t=>createOccupancyGridSpec(e,"occupancy_grid",t))),blockSizes:t}}function createDistanceGridsSpec(e){if(!e.useDistanceGrid)return{assetType:"distance_grids",gridSpecs:[],blockSizes:[]};return{assetType:"distance_grids",gridSpecs:[createOccupancyGridSpec(e,"distance_grid",8)],blockSizes:[8]}}function createSparseGridSpec(e){e.export_array_format;let t=getFieldOrDefault(e,"export_store_rgb_and_density_separately",!1),r={assetType:"sparse_grid",blockIndicesSpec:createSparseGridBlockIndicesSpec(e),separateRgbAndDensity:t};return t?(r.rgbSpec=createSparseGridAssetSpec(e,"sparse_grid_rgb",3),r.densitySpec=createSparseGridAssetSpec(e,"sparse_grid_density",2),r.featuresSpec=createSparseGridAssetSpec(e,"sparse_grid_features",3)):(r.rgbAndDensitySpec=createSparseGridAssetSpec(e,"sparse_grid_rgb_and_density",4),r.featuresSpec=createSparseGridAssetSpec(e,"sparse_grid_features",4)),r}function createSparseGridBlockIndicesSpec(e){const t=e.export_array_format||"png";let r=e.sparse_grid_resolution/e.data_block_size;return{assetType:"sparse_grid_block_indices",filename:`sparse_grid_block_indices.${t}`,shape:[r,r,r],numChannels:3}}function createSparseGridAssetSpec(e,t,r){const a=e.export_array_format||"png";let n=e.num_slices,s=e.atlas_width,i=e.atlas_height,o=e.atlas_depth,l=Math.ceil(o/n),c=[];for(let e=0;e<n;++e){const o=digits(e,3);filename=`${t}_${o}.${a}`,c.push({assetType:`${t}_slice`,shape:[s,i,l],numChannels:r,sliceIndex:e,numSlices:n,filename:filename})}return{assetType:`${t}_slices`,shape:[s,i,o],numChannels:r,sliceSpecs:c,numSlices:n,mergeSlices:getMergeSlices(e)}}function createOccupancyGridSpec(e,t,r){const a=e.export_array_format||"png",n=e.triplane_resolution,s=e.triplane_voxel_size,i=Math.ceil(n/r),o=s*r;const l=getFieldOrDefault(e,"export_slice_occupancy_and_distance_grids",!0)&&i>256;let c=getFieldOrDefault(e,"export_pad_occupancy_and_distance_grids",!0)?4:1,u=[];if(e.legacyGrids||!l){let n=`${t}_${r}.${a}`;e.legacyGrids||(n=`${t}_${r}_000.${a}`),u.push({assetType:`${t}_slice`,shape:[i,i,i],numChannels:c,sliceIndex:0,numSlices:1,filename:n})}else{const e=Math.ceil(i/8);for(let n=0;n<8;++n){let s=`${t}_${r}_${digits(n,3)}.${a}`;u.push({assetType:`${t}_slice`,shape:[i,i,e],numChannels:c,sliceIndex:n,numSlices:8,filename:s})}}return{assetType:`${t}_slices`,shape:[i,i,i],numChannels:c,voxelSize:o,blockSize:r,sliceSpecs:u,numSlices:8,mergeSlices:getMergeSlices(e)}}function createTriplaneSpec(e){const t=e.triplane_resolution;let r={assetType:"triplane",shape:[t,t,3],numSlices:3,voxelSize:e.triplane_voxel_size,separateRgbAndDensity:getFieldOrDefault(e,"export_store_rgb_and_density_separately",!1),featuresSpec:createTriplaneSlicesSpec(e,"triplane_features",4)};return r.separateRgbAndDensity?(r.rgbSpec=createTriplaneSlicesSpec(e,"triplane_rgb",3),r.densitySpec=createTriplaneSlicesSpec(e,"triplane_density",1)):r.rgbAndDensitySpec=createTriplaneSlicesSpec(e,"triplane_rgb_and_density",4),r}function createTriplaneSlicesSpec(e,t,r){const a=e.triplane_resolution;return{assetType:`${t}_slices`,shape:[a,a,3],numChannels:r,numSlices:3,mergeSlices:getMergeSlices(e),sliceSpecs:range(3).map((a=>createPlaneSliceSpec(e,t,r,a)))}}function createPlaneSliceSpec(e,t,r,a){const n=e.export_array_format||"png",s=e.triplane_resolution;let i=t.replace(/^triplane_/,"plane_");return{assetType:`${t}_slice`,shape:[s,s,1],numChannels:r,sliceIndex:a,numSlices:3,filename:`${i}_${a}.${n}`}}function getMergeSlices(e){const t=getFieldOrDefault(e,"export_store_rgb_and_density_separately",!1),r=getFieldOrDefault(e,"merge_slices",!t);if(!t&&!r)throw new Error('Slices must be merged when using "rgb_and_density" images. Please re-export with export_store_rgb_and_density_separately=true and try again.');return r&&t}const baseGoogleApiUrl="https://firebasestorage.googleapis.com/v0/b/test3-2d896.appspot.com/o";let gcsToken=null;function fetchGcsToken(){return gcsToken||(gcsToken=fetch("http://localhost:3001/get-gcs-token").then((e=>{if(!e.ok)throw new Error(`Erreur lors de la récupération du jeton GCS: ${e.status}`);return e.json()})).then((e=>(gcsToken=e.token,setTimeout((()=>{gcsToken=null}),84e4),gcsToken))).catch((e=>{throw console.error("Erreur lors de la récupération du jeton GCS:",e),gcsToken=null,e})),gcsTokenPromise)}function fetchScene(e,t){return{...e,occupancyGridsAsset:fetchAsset(e.occupancyGridsSpec,t),distanceGridsAsset:fetchAsset(e.distanceGridsSpec,t),triplaneAsset:fetchAsset(e.triplaneSpec,t),sparseGridAsset:fetchAsset(e.sparseGridSpec,t)}}function fetchOccupancyGrids(e,t){let r=e.gridSpecs.map((e=>fetchAsset(e,t)));return{...e,gridAssets:r}}function fetchSlices(e,t){let r=e.sliceSpecs.map((e=>fetchAsset(e,t)));return{...e,sliceAssets:r}}function fetchTriplane(e,t){let r={...e,featuresAsset:fetchAsset(e.featuresSpec,t)};return e.separateRgbAndDensity?(r.rgbAsset=fetchAsset(e.rgbSpec,t),r.densityAsset=fetchAsset(e.densitySpec,t)):r.rgbAndDensityAsset=fetchAsset(e.rgbAndDensitySpec,t),r}function fetchArray(e,t){const r=t.dirUrl;if("string"!=typeof r)throw console.error("dirUrl is not a valid string:",r),new Error("dirUrl must be a valid string");if(!e.filename)throw console.error("Spec missing filename:",e),new Error("Spec must contain a valid filename");const a=cleanPath(r),n=e.filename.endsWith(".gz")?e.filename.slice(0,-3):e.filename,s=encodeURIComponent(a),i=`${baseGoogleApiUrl}/users%2Fvisite_3D%2F${s}%2F${n}?alt=media&token=${gcsToken}`;console.log("Fetching from URL:",i);const o=loadAsset(i).then(validateSize(e)).then(onImageLoaded);return{...e,asset:o}}function validateSize(e){return t=>{const r=product(e.shape)*e.numChannels;return console.assert(t.length===r,`Size mismatch for ${e.filename}`,e,t),t}}function cleanPath(e){const t=e.split("/"),r=[];for(let e=0;e<t.length;e++)".."===t[e]?r.length&&r.pop():"."!==t[e]&&""!==t[e]&&r.push(t[e]);return r.join("/")}function fetchSparseGrid(e,t){let r={...e,blockIndicesAsset:fetchAsset(e.blockIndicesSpec,t),featuresAsset:fetchAsset(e.featuresSpec,t)};return e.separateRgbAndDensity?(r.rgbAsset=fetchAsset(e.rgbSpec,t),r.densityAsset=fetchAsset(e.densitySpec,t)):r.rgbAndDensityAsset=fetchAsset(e.rgbAndDensitySpec,t),r}function notImplementedError(e,t){console.error(`${e.assetType} is not yet implemented`,e)}const gFetchRegistry={scene:fetchScene,triplane:fetchTriplane,triplane_rgb_and_density_slices:fetchSlices,triplane_rgb_and_density_slice:fetchArray,triplane_rgb_slices:fetchSlices,triplane_rgb_slice:fetchArray,triplane_density_slices:fetchSlices,triplane_density_slice:fetchArray,triplane_features_slices:fetchSlices,triplane_features_slice:fetchArray,distance_grids:fetchOccupancyGrids,distance_grid_slices:fetchSlices,distance_grid_slice:fetchArray,occupancy_grids:fetchOccupancyGrids,occupancy_grid_slices:fetchSlices,occupancy_grid_slice:fetchArray,sparse_grid:fetchSparseGrid,sparse_grid_block_indices:fetchArray,sparse_grid_rgb_and_density_slices:fetchSlices,sparse_grid_rgb_and_density_slice:fetchArray,sparse_grid_rgb_slices:fetchSlices,sparse_grid_rgb_slice:fetchArray,sparse_grid_density_slices:fetchSlices,sparse_grid_density_slice:fetchArray,sparse_grid_features_slices:fetchSlices,sparse_grid_features_slice:fetchArray};function fetchAsset(e,t){let r=gFetchRegistry[e.assetType];return null==r&&console.error(`Failed to find fetchFn for assetType ${e.assetType}`,e),r(e,t)}function createEmptyVolumeTexture(e,t,r,a,n){let s=new THREE.DataTexture3D(null,e,t,r);return s.internalFormat=getInternalFormat(a),s.format=a,s.generateMipmaps=!1,s.magFilter=s.minFilter=n,s.wrapS=s.wrapT=s.wrapR=THREE.ClampToEdgeWrapping,s.type=THREE.UnsignedByteType,s.unpackAlignment=1,gRenderer.initTexture(s),s}function createEmptyTriplaneTextureArray(e,t,r,a){let n=new THREE.DataTexture2DArray(null,e,t,r);return n.internalFormat=getInternalFormat(a),n.format=a,n.generateMipmaps=!1,n.magFilter=n.minFilter=THREE.LinearFilter,n.wrapS=n.wrapT=n.wrapR=THREE.ClampToEdgeWrapping,n.type=THREE.UnsignedByteType,n.unpackAlignment=1,gRenderer.initTexture(n),n}function getInternalFormat(e){if(e==THREE.RedFormat)return"R8";if(e==THREE.LuminanceAlphaFormat)return"LUMINANCE_ALPHA";if(e==THREE.RGBFormat)return"RGB";if(e==THREE.RGBAFormat)return"RGBA";throw new Error(`Unrecognized THREE.js format: ${e}`)}function createEmptySceneTexture(e){return{textureType:"scene",occupancyGridsTexture:createEmptyTexture(e.occupancyGridsSpec),distanceGridsTexture:createEmptyTexture(e.distanceGridsSpec),triplaneTexture:createEmptyTexture(e.triplaneSpec),sparseGridTexture:createEmptyTexture(e.sparseGridSpec)}}function createEmptyOccupancyGridsTexture(e){return{textureType:e.assetType.replace(/_slices$/,""),gridTextures:e.gridSpecs.map(createEmptyTexture)}}function createEmptyOccupancyGridTexture(e){return{textureType:e.assetType.replace(/_slices$/,""),texture:createEmptyVolumeTexture(...e.shape,THREE.RedFormat,THREE.NearestFilter)}}function createEmptyTriplaneTexture(e){let t={textureType:"triplane",featuresTexture:createEmptyTexture(e.featuresSpec)};if(e.separateRgbAndDensity)t.rgbTexture=createEmptyTexture(e.rgbSpec),t.densityTexture=createEmptyTexture(e.densitySpec);else{let r=e.rgbAndDensitySpec.shape;t.rgbTexture=createEmptyTexture({assetType:"triplane_rgb_slices",shape:r}),t.densityTexture=createEmptyTexture({assetType:"triplane_density_slices",shape:r})}return t}function createEmptyTriplaneSlicesTexture(e){let t=e.assetType.replace(/_slices$/,""),r={triplane_density:THREE.RedFormat,triplane_rgb:THREE.RGBFormat,triplane_features:THREE.RGBAFormat}[t];return console.assert(null!=r,e),{textureType:t,texture:createEmptyTriplaneTextureArray(...e.shape,r)}}function createEmptySparseGridTexture(e){let t=(e,t)=>createEmptyVolumeTexture(...e.shape,t,THREE.LinearFilter),r=e.separateRgbAndDensity?e.rgbSpec:e.rgbAndDensitySpec,a=e.separateRgbAndDensity?e.densitySpec:e.rgbAndDensitySpec,n=t(r,THREE.RGBFormat),s=t(a,THREE.LuminanceAlphaFormat),i=t(e.featuresSpec,THREE.RGBFormat);return{textureType:"sparse_grid",blockIndicesTexture:{textureType:"sparse_grid_block_indices",texture:createEmptyVolumeTexture(...e.blockIndicesSpec.shape,THREE.RGBFormat,THREE.NearestFilter)},rgbTexture:{textureType:"sparse_grid_rgb",texture:n},densityTexture:{textureType:"sparse_grid_density",texture:s},featuresTexture:{textureType:"sparse_grid_features",texture:i}}}const gCreateEmptyTextureRegistry={scene:createEmptySceneTexture,triplane:createEmptyTriplaneTexture,triplane_rgb_slices:createEmptyTriplaneSlicesTexture,triplane_density_slices:createEmptyTriplaneSlicesTexture,triplane_features_slices:createEmptyTriplaneSlicesTexture,distance_grids:createEmptyOccupancyGridsTexture,distance_grid_slices:createEmptyOccupancyGridTexture,occupancy_grids:createEmptyOccupancyGridsTexture,occupancy_grid_slices:createEmptyOccupancyGridTexture,sparse_grid:createEmptySparseGridTexture};function createEmptyTexture(e){let t=gCreateEmptyTextureRegistry[e.assetType];return null==t&&console.error(`Failed to find loadFn for assetType ${e.assetType}`,e),t(e)}function prepareScenePayload(e){return{textureType:"scene",occupancyGridsPayload:prepareTexturePayload(e.occupancyGridsAsset),distanceGridsPayload:prepareTexturePayload(e.distanceGridsAsset),triplanePayload:prepareTexturePayload(e.triplaneAsset),sparseGridPayload:prepareTexturePayload(e.sparseGridAsset)}}function prepareOccupancyGridsPayload(e){return{textureType:e.assetType,gridPayloads:e.gridAssets.map(prepareTexturePayload)}}function prepareOccupancyGridPayload(e){return e.mergeSlices?prepareOccupancyGridMergedPayload(e):prepareOccupancyGridSlicesPayload(e)}function prepareOccupancyGridMergedPayload(e){return console.assert(e.assetType.endsWith("_slices"),e),{textureType:e.assetType.replace(/_slices$/,""),shape:e.shape,numChannels:e.numChannels,payload:mergeSlices(e,{1:GridTextureSource.RED_FROM_RED,4:GridTextureSource.ALPHA_FROM_RGBA}[e.numChannels],GridTextureDestination.RED_IN_RED)}}function prepareOccupancyGridSlicesPayload(e){return console.assert(e.assetType.endsWith("_slices"),e),{textureType:e.assetType.replace(/_slices$/,""),shape:e.shape,numChannels:e.numChannels,slicePayloads:e.sliceAssets.map(prepareTexturePayload)}}function prepareOccupancyGridSlicePayload(e){console.assert(e.assetType.endsWith("_slice"),e);let t=null;if(1==e.numChannels)t=e.asset;else{if(4!=e.numChannels)throw new Error("Unrecognized number of input channels",e);t=mergeSlices({shape:e.shape,numSlices:1,sliceAssets:[{...e,sliceIndex:0,numSlices:1}]},GridTextureSource.ALPHA_FROM_RGBA,GridTextureDestination.RED_IN_RED)}return{textureType:e.assetType,shape:e.shape,numChannels:e.numChannels,sliceIndex:e.sliceIndex,numSlices:e.numSlices,payload:t}}function prepareTriplanePayload(e){let t={textureType:"triplane",featuresPayload:preparePlanePayload(e.featuresAsset,"triplane_features",GridTextureSource.RGBA_FROM_RGBA,GridTextureDestination.RGBA_IN_RGBA)};return e.separateRgbAndDensity?(t.rgbPayload=preparePlanePayload(e.rgbAsset,"triplane_rgb",GridTextureSource.RGB_FROM_RGB,GridTextureDestination.RGB_IN_RGB),t.densityPayload=preparePlanePayload(e.densityAsset,"triplane_density",GridTextureSource.RED_FROM_RED,GridTextureDestination.RED_IN_RED)):(t.rgbPayload=preparePlanePayload(e.rgbAndDensityAsset,"triplane_rgb",GridTextureSource.RGB_FROM_RGBA,GridTextureDestination.RGB_IN_RGB),t.densityPayload=preparePlanePayload(e.rgbAndDensityAsset,"triplane_density",GridTextureSource.ALPHA_FROM_RGBA,GridTextureDestination.RED_IN_RED)),t}function preparePlanePayload(e,t,r,a){let n={textureType:t,shape:e.shape,numChannels:e.numChannels};return e.mergeSlices?n.payload=mergeSlices(e,r,a):n.slicePayloads=e.sliceAssets.map((e=>preparePlaneSlicePayload(e,r,a))),n}function preparePlaneSlicePayload(e,t,r){let a=null;return a=t.format==r.format&&t.channels==r.channels?e.asset:mergeSlices({shape:e.shape,numSlices:1,sliceAssets:[{...e,sliceIndex:0,numSlices:1}]},t,r),{textureType:e.assetType,shape:e.shape,sliceIndex:e.sliceIndex,numSlices:e.numSlices,numChannels:e.numChannels,payload:a}}function prepareArrayPayload(e){return{textureType:e.assetType,payload:e.asset,shape:e.shape,numChannels:e.numChannels}}function prepareSparseGridPayload(e){let t={textureType:"sparse_grid",blockIndicesPayload:prepareTexturePayload(e.blockIndicesAsset),featuresPayload:prepareTexturePayload(e.featuresAsset)};return e.separateRgbAndDensity?(t.rgbPayload=prepareTexturePayload(e.rgbAsset),t.densityPayload=prepareTexturePayload(e.densityAsset)):(t.rgbPayload=prepareTexturePayload(e.rgbAndDensityAsset),t.densityPayload=prepareSparseGridDensityPayload(e)),t}function prepareSparseGridGenericPayload(e){return e.mergeSlices?prepareSparseGridGenericMergedPayload(e):prepareSparseGridGenericSlicesPayload(e)}function prepareSparseGridGenericMergedPayload(e){let t=e.assetType.replace(/_slices$/,"");t.includes("rgb_and_density")&&(t=t.replace(/rgb_and_density$/,"rgb"));let r={2:GridTextureSource.LA_FROM_LUMINANCE_ALPHA,3:GridTextureSource.RGB_FROM_RGB,4:GridTextureSource.RGB_FROM_RGBA},a={2:GridTextureDestination.LA_IN_LUMINANCE_ALPHA,3:GridTextureDestination.RGB_IN_RGB,4:GridTextureDestination.RGB_IN_RGB},n=mergeSlices(e,r[e.numChannels],a[e.numChannels]);return{textureType:t,shape:e.shape,numChannels:e.numChannels,payload:n}}function prepareSparseGridGenericSlicesPayload(e){let t=e.assetType.replace(/_slices$/,"");return t.includes("rgb_and_density")&&(t=t.replace(/rgb_and_density$/,"rgb")),{textureType:t,shape:e.shape,numChannels:e.numChannels,numSlices:e.numSlices,slicePayloads:e.sliceAssets.map(prepareTexturePayload)}}function prepareSparseGridGenericSlicePayload(e){let t=e.assetType,r=null;if("sparse_grid_rgb_slice"==t&&3==e.numChannels||"sparse_grid_density_slice"==t&&2==e.numChannels||"sparse_grid_features_slice"==t&&3==e.numChannels)r=e.asset;else{let t={2:GridTextureSource.LA_FROM_LUMINANCE_ALPHA,3:GridTextureSource.RGB_FROM_RGB,4:GridTextureSource.RGB_FROM_RGBA},a={2:GridTextureDestination.LA_IN_LUMINANCE_ALPHA,3:GridTextureDestination.RGB_IN_RGB,4:GridTextureDestination.RGB_IN_RGB};r=mergeSlices({shape:e.shape,numSlices:1,sliceAssets:[{...e,sliceIndex:0,numSlices:1}]},t[e.numChannels],a[e.numChannels])}let a=t;return a.includes("rgb_and_density")&&(a=a.replace(/_rgb_and_density$/,"rgb")),{textureType:a,shape:e.shape,numChannels:e.numChannels,sliceIndex:e.sliceIndex,numSlices:e.numSlices,payload:r}}function prepareSparseGridDensityPayload(e){return{textureType:"sparse_grid_density",shape:e.rgbAndDensityAsset.shape,numChannels:2,payload:mergeSparseGridDensity(e)}}const gPrepareTexturePayloadRegistry={scene:prepareScenePayload,triplane:prepareTriplanePayload,distance_grids:prepareOccupancyGridsPayload,distance_grid_slices:prepareOccupancyGridPayload,distance_grid_slice:prepareOccupancyGridSlicePayload,occupancy_grids:prepareOccupancyGridsPayload,occupancy_grid_slices:prepareOccupancyGridPayload,occupancy_grid_slice:prepareOccupancyGridSlicePayload,sparse_grid:prepareSparseGridPayload,sparse_grid_block_indices:prepareArrayPayload,sparse_grid_rgb_and_density_slices:prepareSparseGridGenericPayload,sparse_grid_rgb_and_density_slice:prepareSparseGridGenericSlicePayload,sparse_grid_rgb_slices:prepareSparseGridGenericPayload,sparse_grid_rgb_slice:prepareSparseGridGenericSlicePayload,sparse_grid_density_slices:prepareSparseGridGenericPayload,sparse_grid_density_slice:prepareSparseGridGenericSlicePayload,sparse_grid_features_slices:prepareSparseGridGenericPayload,sparse_grid_features_slice:prepareSparseGridGenericSlicePayload};function prepareTexturePayload(e){let t=gPrepareTexturePayloadRegistry[e.assetType];return null==t&&console.error(`Failed to find loadFn for assetType ${e.assetType}`,e),t(e)}function populateScene(e,t){let r=[populateTexture(e.occupancyGridsTexture,t.occupancyGridsPayload),populateTexture(e.distanceGridsTexture,t.distanceGridsPayload),populateTexture(e.triplaneTexture,t.triplanePayload),populateTexture(e.sparseGridTexture,t.sparseGridPayload)];return Promise.all(r)}function populateOccupancyGridsTexture(e,t){console.assert(e.gridTextures.length==t.gridPayloads.length,e,t);let r=range(e.gridTextures.length).map((r=>populateTexture(e.gridTextures[r],t.gridPayloads[r])));return Promise.all(r)}function populateSparseGridTexture(e,t){let r=[populateTexture(e.blockIndicesTexture,t.blockIndicesPayload),populateTexture(e.rgbTexture,t.rgbPayload),populateTexture(e.densityTexture,t.densityPayload),populateTexture(e.featuresTexture,t.featuresPayload)];return Promise.all(r)}function populateTriplaneTexture(e,t){return Promise.all([populateTexture(e.rgbTexture,t.rgbPayload),populateTexture(e.densityTexture,t.densityPayload),populateTexture(e.featuresTexture,t.featuresPayload)])}async function populateArrayTexture(e,t){if(null==t.payload)throw new Error("Unclear how to ingest payload",e,t);e.texture.image.data=await t.payload,e.texture.needsUpdate=!0}function populateArrayTextureWithWebGL(e,t){if(null!=t.payload)return populateArrayTextureMergedWithWebGL(e,t);if(null!=t.slicePayloads){let r=t.slicePayloads.map((t=>populateArrayTextureSliceWithWebGL(e,t)));return Promise.all(r)}throw new Error("Unclear how to ingest payload",e,t)}async function populateArrayTextureSliceWithWebGL(e,t){let r=gRenderer.getContext();const a=t.shape[0],n=t.shape[1],s=t.shape[2],i=t.sliceIndex;let o=e.texture.format,{glFormat:l,glInternalFormat:c,numChannels:u}=threeFormatToOpenGLFormat(r,o),d=await t.payload;let p,g,m=gRenderer.properties.get(e.texture).__webglTexture;console.assert(null!=m,e),e.texture instanceof THREE.DataTexture3D?(p=r.TEXTURE_BINDING_3D,g=r.TEXTURE_3D):e.texture instanceof THREE.DataTexture2DArray&&(p=r.TEXTURE_BINDING_2D_ARRAY,g=r.TEXTURE_2D_ARRAY);let h=r.getParameter(p);r.bindTexture(g,m);performance.mark(`${e.textureType}-start`);r.texSubImage3D(g,0,0,0,i*s,a,n,s,l,r.UNSIGNED_BYTE,d,0);performance.mark(`${e.textureType}-end`);performance.measure(`${e.textureType}-duration`,`${e.textureType}-start`,`${e.textureType}-end`),r.bindTexture(g,h)}async function populateArrayTextureMergedWithWebGL(e,t){return populateArrayTextureSliceWithWebGL(e,{...t,sliceIndex:0,numSlices:1})}function threeFormatToOpenGLFormat(e,t){if(t==THREE.RGBAFormat)return{numChannels:4,glFormat:e.RGBA,glInternalFormat:e.RGBA};if(t==THREE.RGBFormat)return{numChannels:3,glFormat:e.RGB,glInternalFormat:e.RGB};if(t==THREE.LuminanceAlphaFormat)return{numChannels:2,glFormat:e.LUMINANCE_ALPHA,glInternalFormat:e.LUMINANCE_ALPHA};if(t==THREE.RedFormat)return{numChannels:1,glFormat:e.RED,glInternalFormat:e.R8};throw new Error(`Unrecognized three format: ${t}`)}const gPopulateTextureRegistry={scene:populateScene,triplane:populateTriplaneTexture,triplane_rgb:populateArrayTextureWithWebGL,triplane_density:populateArrayTextureWithWebGL,triplane_features:populateArrayTextureWithWebGL,distance_grids:populateOccupancyGridsTexture,distance_grid:populateArrayTextureWithWebGL,occupancy_grids:populateOccupancyGridsTexture,occupancy_grid:populateArrayTextureWithWebGL,sparse_grid:populateSparseGridTexture,sparse_grid_block_indices:populateArrayTextureWithWebGL,sparse_grid_rgb:populateArrayTextureWithWebGL,sparse_grid_density:populateArrayTextureWithWebGL,sparse_grid_features:populateArrayTextureWithWebGL};function populateTexture(e,t){let r=gPopulateTextureRegistry[e.textureType];return null==r&&console.error(`Failed to find loadFn for assetType ${e.textureType}`,e),r(e,t)}const NEEDS_NEW_SUBMODEL=-1,LOADING=0,READY=1;let gSubmodelSceneContents={},gSubmodelCacheSize=10,gRayMarchTextureBuffers=[{si:0,state:-1,texture:null},{si:0,state:-1,texture:null}],gActiveRayMarchTextureBuffer=0,gRayMarchScene=null;function getRayMarchScene(){if(null==gRayMarchScene)throw new Error("gRayMarchScene has not been initialized yet!");return gRayMarchScene}function getActiveSubmodelIndex(){return gRayMarchTextureBuffers[gActiveRayMarchTextureBuffer].si}function getActiveSubmodelContent(){return getSubmodelContent(getActiveSubmodelIndex())}function getSubmodelScale(e){return getSubmodelContent(e).params.submodel_scale}function getSubmodelScaleFactor(e){let t=getSubmodelContent(e);return getSubmodelScale(e)/Math.cbrt(t.params.num_submodels)}function getSubmodelContent(e){return gSubmodelSceneContents[e]}function registerSubmodelContent(e,t){gSubmodelSceneContents[e]=t}function getDeferredMlp(){return console.assert(null!=gDeferredMlp),gDeferredMlp}function registerDeferredMlp(e){validateDeferredMlp(e),gDeferredMlp=e}function getCurrentTextureUsageInBytes(){let e=0;for(rmtb of gRayMarchTextureBuffers)e+=getTextureSizeInBytes(rmtb.texture);return e}function setCurrentRayMarchScene(e){let t=gActiveRayMarchTextureBuffer,r=gRayMarchTextureBuffers[t],a=(t+1)%2,n=gRayMarchTextureBuffers[a];if(null==getSubmodelContent(e))return Promise.resolve();if(getSubmodelContent(e).lastTouched=Date.now(),e==r.si&&r.state>=0)return Promise.resolve();if(e==n.si&&1==n.state){return console.log(`Switching to buffer ${a} for submodel #${e}`),setTextureUniforms(getSubmodelContent(e).params,n.texture),gActiveRayMarchTextureBuffer=a,Promise.resolve()}return n.state>=0&&n.state<1?Promise.resolve():(console.log(`Preparing texture buffer #${a} for submodel #${e}`),n.si=e,n.state=0,Promise.resolve().then((()=>{reinitializeSparseGridTextures(n);let e=getSubmodelContent(n.si);if(null==e.payload){console.log(`Fetching assets for submodel #${n.si}`);let t=prepareTexturePayload(fetchAsset(e.spec,e.router));e.payload=t}return console.log(`Populating textures for submodel #${n.si} into buffer #${a}`),populateTexture(n.texture,e.payload)})).then((()=>{n.state=1,console.log(`Submodel #${n.si} is ready for rendering`),hideLoading()})))}function garbageCollectSubmodelPayloads(){let e=[];for(let t of Object.keys(gSubmodelSceneContents)){let r=getSubmodelContent(t);null!=r.payload&&e.push({lastTouched:r.lastTouched||0,si:t})}e.sort(((e,t)=>e.lastTouched-t.lastTouched));for(let t=0;t<e.length-gSubmodelCacheSize;++t){let r=e[t].si;console.log(`Deleting payload for submodel #${r}`),getSubmodelContent(r).payload=null}}function initializeSceneContent(e,t){return{spec:createSceneSpec(e),params:e,router:t,payload:null}}function reinitializeSparseGridTextures(e){let t=e.texture.sparseGridTexture;t.blockIndicesTexture.texture.dispose(),t.rgbTexture.texture.dispose(),t.densityTexture.texture.dispose(),t.featuresTexture.texture.dispose();let r=getSubmodelContent(e.si).spec.sparseGridSpec;e.texture.sparseGridTexture=createEmptyTexture(r)}async function initializePingPongBuffers(e){let t=getSubmodelContent(e);gRayMarchScene=await initializeRayMarchScene(e,t);for(let e of gRayMarchTextureBuffers)e.texture=createEmptyTexture(t.spec);setTextureUniforms(t.params,gRayMarchTextureBuffers[0].texture),gActiveRayMarchTextureBuffer=0}async function initializeDeferredMlp(e){let t=getSubmodelContent(e),r=t.params;if(r.export_store_deferred_mlp_separately){return loadJSONFile(t.router.translate("deferred_mlp.json")).then(registerDeferredMlp)}return registerDeferredMlp(r.deferred_mlp)}function setTextureUniforms(e,t){let r=getRayMarchScene().children[0].material.uniforms,a=t.occupancyGridsTexture.gridTextures,n=a.length;for(let e=0;e<n;++e){let t=a[e];r["occupancyGrid_L"+(n-e-1)].value=t.texture}if(e.useDistanceGrid){let e=t.distanceGridsTexture.gridTextures[0].texture;r.distanceGrid.value=e}let s=t.triplaneTexture;r.planeDensity.value=s.densityTexture.texture,r.planeRgb.value=s.rgbTexture.texture,r.planeFeatures.value=s.featuresTexture.texture;let i=t.sparseGridTexture;r.sparseGridBlockIndices.value=i.blockIndicesTexture.texture,r.sparseGridDensity.value=i.densityTexture.texture,r.sparseGridRgb.value=i.rgbTexture.texture,r.sparseGridFeatures.value=i.featuresTexture.texture,r.atlasSize.value=new THREE.Vector3(e.atlas_width,e.atlas_height,e.atlas_depth)}function getTextureSizeInBytes(e){let t=0,r=e=>{if(null==e)return 0;let t=e.texture.image;return t.height*t.width*t.depth},a=e.occupancyGridsTexture.gridTextures,n=a.length;for(let e=0;e<n;++e){t+=1*r(a[e])}if(e.distanceGridsTexture.gridTextures.length>0){t+=1*r(e.distanceGridsTexture.gridTextures[0])}let s=e.triplaneTexture;t+=3*r(s.rgbTexture),t+=1*r(s.densityTexture),t+=4*r(s.featuresTexture);let i=e.sparseGridTexture;return t+=1*r(i.blockIndicesTexture),t+=3*r(i.rgbTexture),t+=1*r(i.densityTexture),t+=4*r(i.featuresTexture),t}async function initializeRayMarchScene(e,t){let r=t.params,a=t.spec,n=kRayMarchFragmentShaderHeader;n+=await loadTextFile("viewdependency.glsl"),n+=await loadTextFile("fragment.glsl"),n=rewriteViewDependenceDefinitions(r,n);let s=new THREE.Matrix3;s.set(-1,0,0,0,0,1,0,1,0);let i=new THREE.Vector3(-2,-2,-2);n="#define kMinPosition vec3("+Number(i.x).toFixed(10)+", "+Number(i.y).toFixed(10)+", "+Number(i.z).toFixed(10)+")\n"+n,n="#define kSubmodelScale "+Number(getSubmodelScale(e)).toFixed(10)+"\n"+n,n="#define kStepMult "+gStepMult+"\n"+n,n="#define kRangeFeaturesMin "+Number(r.range_features[0]).toFixed(10)+"\n"+n,n="#define kRangeFeaturesMax "+Number(r.range_features[1]).toFixed(10)+"\n"+n,n="#define kRangeDensityMin "+Number(r.range_density[0]).toFixed(10)+"\n"+n,n="#define kRangeDensityMax "+Number(r.range_density[1]).toFixed(10)+"\n"+n;let o={bias_0:{value:null},bias_1:{value:null},bias_2:{value:null},weightsZero:{value:null},weightsOne:{value:null},weightsTwo:{value:null},displayMode:{value:gDisplayMode-0},minPosition:{value:i},world_T_cam:{value:new THREE.Matrix4},cam_T_clip:{value:new THREE.Matrix4},worldspaceROpengl:{value:s}};occupancyUniforms={};let l=a.occupancyGridsSpec.gridSpecs,c=l.length;for(let e=0;e<c;++e){let t=l[e],r=c-e-1;n="#define kVoxelSizeOccupancy_L"+r+" "+Number(t.voxelSize).toFixed(10)+"\n"+n,n="#define kGridSizeOccupancy_L"+r+" vec3("+Number(t.shape[0]).toFixed(10)+", "+Number(t.shape[1]).toFixed(10)+", "+Number(t.shape[2]).toFixed(10)+")\n"+n,occupancyUniforms["occupancyGrid_L"+r]={value:null}}if(o=extend(o,occupancyUniforms),r.useDistanceGrid){let e=a.distanceGridsSpec.gridSpecs[0];n="#define USE_DISTANCE_GRID\n"+n,n="#define kVoxelSizeDistance "+Number(e.voxelSize).toFixed(10)+"\n"+n,n="#define kGridSizeDistance vec3("+Number(e.shape[0]).toFixed(10)+", "+Number(e.shape[1]).toFixed(10)+", "+Number(e.shape[2]).toFixed(10)+")\n"+n,distanceUniforms={distanceGrid:{value:null}},o=extend(o,distanceUniforms)}let u=new THREE.Color(.5,.5,.5);r.backgroundColor&&(u=new THREE.Color(r.backgroundColor)),n="#define kBackgroundColor vec3("+Number(u.r).toFixed(10)+", "+Number(u.g).toFixed(10)+", "+Number(u.b).toFixed(10)+")\n"+n,(gExposure||r.default_exposure)&&(r.default_exposure&&(gExposure=parseFloat(r.default_exposure)),n="#define USE_EXPOSURE\n"+n,exposureUniforms={exposure:{value:gExposure}},o=extend(o,exposureUniforms));n="#define ACTIVATION_FN "+(r.activation?r.activation:"elu")+"\n"+n,null!==r.feature_gating&&void 0!==r.feature_gating&&!0!==r.feature_gating||(n="#define USE_FEATURE_GATING\n"+n),"vfr"===r.deferred_rendering_mode&&(n="#define USE_VFR\n"+n),"coarse_sum"===r.merge_features_combine_op&&(n="#define USE_FEATURE_CONCAT\n"+n),r.useBits&&(n="#define USE_BITS\n"+n),r.useLargerStepsWhenOccluded&&(n="#define LARGER_STEPS_WHEN_OCCLUDED\n"+n,n="#define kVisibilityDelay "+Number(r.step_size_visibility_delay).toFixed(10)+"\n"+n);let d=new THREE.Vector2(...a.triplaneSpec.shape);n="#define kTriplaneVoxelSize "+Number(r.triplane_voxel_size).toFixed(10)+"\n"+n,n="#define kTriplaneGridSize vec2("+Number(d.x).toFixed(10)+", "+Number(d.y).toFixed(10)+")\n"+n;o=extend(o,{planeDensity:{value:null},planeRgb:{value:null},planeFeatures:{value:null}}),n="#define kDataBlockSize "+Number(r.data_block_size).toFixed(10)+"\n"+n,n="#define kSparseGridVoxelSize "+Number(r.sparse_grid_voxel_size).toFixed(10)+"\n"+n,n="#define kSparseGridGridSize vec3("+Number(r.sparse_grid_resolution).toFixed(10)+", "+Number(r.sparse_grid_resolution).toFixed(10)+", "+Number(r.sparse_grid_resolution).toFixed(10)+")\n"+n;o=extend(o,{sparseGridBlockIndices:{value:null},sparseGridDensity:{value:null},sparseGridRgb:{value:null},sparseGridFeatures:{value:null},atlasSize:{value:null}});let p=new THREE.ShaderMaterial({uniforms:o,vertexShader:kRayMarchVertexShader,fragmentShader:n,vertexColors:!0});p.side=THREE.DoubleSide,p.depthTest=!1,p.needsUpdate=!0;const g=new THREE.PlaneBufferGeometry(...gViewportDims);let m=new THREE.Mesh(g,p);m.position.z=-100,m.frustumCulled=!1;let h=new THREE.Scene;return h.add(m),h.autoUpdate=!1,h}function validateDeferredMlp(e){const t=e["ResampleDense_0/kernel"]?"ResampleDense":"Dense";for(let r=0;r<3;r++){const a=`${t}_${r}`;let n=e[`${a}/kernel`].shape,s=e[`${a}/bias`].shape;if("ResampleDense"===t){let e=n[1];console.assert(e===n[2]&&e===n[3]),console.assert(n[0]===s[0]&&n[1]===s[1]&&n[2]===s[2]&&n[3]===s[3])}}}class WorkerPool{constructor(e,t){let r=this;e=e||2,this.workers=[];for(let a=0;a<e;++a){let e=new Worker(t);e.onmessage=e=>{r.onmessage(e)},this.workers.push(e)}this.nextworker=0,this.callbacks={},this.i=0}submit(e,t){const r=this.i;this.callbacks[r]=t,this.i+=1;const a=this.nextworker,n=this.workers[a];this.nextworker=(a+1)%this.workers.length,n.postMessage({i:r,request:e})}onmessage(e){const t=e.data,r=t.i;(0,this.callbacks[r])(t.result),delete this.callbacks[r]}}let gStats=null,gUseSubmodel=!1,gSubmodelTransform=null,gDeferredMlp=null;const DisplayModeType={DISPLAY_NORMAL:0,DISPLAY_DIFFUSE:1,DISPLAY_FEATURES:2,DISPLAY_VIEW_DEPENDENT:3,DISPLAY_COARSE_GRID:4};let gDisplayMode=DisplayModeType.DISPLAY_NORMAL,gBenchmark=!1,gFrameMult=1,gLoadAssetsWorker=new WorkerPool(4,"loadpng.worker.js"),gCopySliceWorker=new WorkerPool(4,"copyslices.worker.js");const kRayMarchVertexShader="\nvarying vec3 vOrigin;\nvarying vec3 vDirection;\nuniform mat4 world_T_cam;\nuniform mat4 cam_T_clip;\n\nvoid main() {\n vec4 posClip = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n gl_Position = posClip;\n posClip /= posClip.w;\n\n vec4 originCam = vec4(0.0, 0.0, 0.0, 1.0);\n vec4 nearPointCam = cam_T_clip * vec4(posClip.x, posClip.y, -1.0, 1.0);\n nearPointCam /= -nearPointCam.z;\n\n vec4 originWorld = world_T_cam * originCam;\n vec4 nearPointWorld = world_T_cam * nearPointCam;\n vOrigin = originWorld.xyz / originWorld.w;\n vDirection = nearPointWorld.xyz / nearPointWorld.w - vOrigin;\n}\n",kRayMarchFragmentShaderHeader="\nprecision highp float;\n\nvarying vec3 vOrigin;\nvarying vec3 vDirection;\n\nuniform int displayMode;\n\nuniform mat3 worldspaceROpengl;\nuniform float nearPlane;\n\n#ifdef USE_DISTANCE_GRID\nuniform highp sampler3D distanceGrid;\nuniform highp sampler3D occupancyGrid_L0;\n#else\nuniform highp sampler3D occupancyGrid_L0;\nuniform highp sampler3D occupancyGrid_L1;\nuniform highp sampler3D occupancyGrid_L2;\n#ifndef USE_BITS\nuniform highp sampler3D occupancyGrid_L3;\nuniform highp sampler3D occupancyGrid_L4;\n#endif\n#endif\n\nuniform vec4 bias_0[NUM_CHANNELS_ONE/4];\nuniform vec4 bias_1[NUM_CHANNELS_TWO/4];\nuniform vec4 bias_2[NUM_CHANNELS_THREE/4];\n\nuniform highp sampler2D weightsZero;\nuniform highp sampler2D weightsOne;\nuniform highp sampler2D weightsTwo;\n\n#ifdef USE_EXPOSURE\nuniform float exposure;\n#endif\n\nuniform vec3 atlasSize;\n\nuniform highp sampler3D sparseGridBlockIndices;\nuniform highp sampler3D sparseGridDensity;\nuniform highp sampler3D sparseGridRgb;\nuniform highp sampler3D sparseGridFeatures;\n\n// need to use texture arrays, otherwise we exceed max texture unit limit\nuniform highp sampler2DArray planeDensity;\nuniform highp sampler2DArray planeRgb;\nuniform highp sampler2DArray planeFeatures;\n";let gRenderer=null,gSubmodelCount=1,gCamera=null,gViewportDims=[640,480],gNumTextures=0,gLoadedTextures=0,gSubmodelForceIndex=-1;function extend(e,t){for(let r in t)t.hasOwnProperty(r)&&(e[r]=t[r]);return e}function error(e){const t=document.getElementById("error");t.textContent=e,t.style.display="block"}function create(e,t){const r=document.createElement(e);return t&&(r.className=t),r}function digits(e,t){const r=""+e;return r.length>=t?r:("00000"+r).substr(-t)}function setupViewport(e,t){gViewportDims=[e,t]}function range(e){return[...Array(e).keys()]}function product(e){result=1;for(let t of e)result*=t;return result}function sum(e){result=1;for(let t of e)result+=t;return result}function setDims(e,t,r){e.style.width=t.toFixed(2)+"px",e.style.height=r.toFixed(2)+"px"}function hideLoading(){document.getElementById("Loading").style.display="none",document.getElementById("loading-container").style.display="none"}function showLoading(){document.getElementById("Loading").style.display="none",document.getElementById("loading-container").style.display="none"}function isLoading(){return"none"!==document.getElementById("Loading").style.display}function onImageFetch(e){return gNumTextures++,updateLoadingProgress(),e}function onImageLoaded(e){return gLoadedTextures++,updateLoadingProgress(),e}function updateLoadingProgress(){let e=document.getElementById("image-progress");const t=gNumTextures>0?gNumTextures:"?";e.innerHTML="Loading images: "+gLoadedTextures+"/"+t}function isRendererUnsupported(){let e=document.getElementById("Loading"),t=document.getElementsByTagName("canvas")[0].getContext("webgl2");return t?!t.getExtension("WEBGL_debug_renderer_info")&&(e.innerHTML="Error: Could not fetch renderer info. Is your machine equipped with a discrete GPU?",!0):(e.innerHTML="Error: WebGL2 context not found. Is your machine equipped with a discrete GPU?",!0)}function sleep(e){return new Promise((t=>setTimeout(t,e)))}function submodelAssetPath(e,t){let r="";if(gUseSubmodel){return r=`../sm_${String(e).padStart(3,"0")}`,null==t?r:`${r}/${t}`}return t}function positionToSubmodel(e,t){if(0==gUseSubmodel)return 0;if(gSubmodelForceIndex>=0)return gSubmodelForceIndex;let r=new THREE.Vector3(-e.x,e.z,e.y),a=2/t.submodel_voxel_size,n=r.addScalar(1).divideScalar(2);n=n.multiplyScalar(a);let s=n.floor().clampScalar(0,a-1);const i=(s.x*a+s.y)*a+s.z;return t.sm_to_params[i]}function submodelCenter(e,t){if(0==gUseSubmodel)return new THREE.Vector3(0,0,0);let r=t.submodel_voxel_size,a=2/r,n=t.params_to_sm[e],s=n%a,i=(n-s)/a%a,o=(n-s-i*a)/a/a;return o=a-1-o,[i,s]=[s,i],new THREE.Vector3((o+.5)*r-1,(i+.5)*r-1,(s+.5)*r-1)}function submodelTransform(e,t){const r=submodelCenter(e,t),a=t.submodel_scale;let n=new THREE.Matrix4;n.makeScale(a,a,a);let s=new THREE.Matrix4;return s.makeTranslation(-r.x,-r.y,-r.z),submodel_matrix=new THREE.Matrix4,submodel_matrix.multiplyMatrices(n,s),submodel_matrix}async function fetchAndRetryIfNecessary(e){const t=await e();return 429===t.status?(await sleep(500),fetchAndRetryIfNecessary(e)):t}function loadAsset(e){return new Promise((t=>{gLoadAssetsWorker.submit({url:e},t)}))}function mergeSlices(e,t,r){let a=e.sliceAssets.map((e=>e.asset));return Promise.all(a).then((a=>{let n=range(a.length).map((t=>({...e.sliceAssets[t],asset:a[t]}))),s={asset:{...e,sliceAssets:n},src:t,dst:r,fn:"mergeSlices"};return new Promise((e=>{gCopySliceWorker.submit(s,e)}))}))}function mergeSparseGridDensity(e){let t=e=>Promise.all(e.sliceAssets.map((e=>e.asset))),r=[t(e.rgbAndDensityAsset),t(e.featuresAsset)];return Promise.all(r).then((t=>{let r=t[0],a=t[1],n=(e,t)=>{let r=range(t.length).map((r=>({...e.sliceAssets[r],asset:t[r]})));return{...e,sliceAssets:r}},s=n(e.rgbAndDensityAsset,r),i=n(e.featuresAsset,a),o={asset:{assetType:e.assetType,rgbAndDensityAsset:s,featuresAsset:i},fn:"mergeSparseGridDensity"};return new Promise((e=>{gCopySliceWorker.submit(o,e)}))}))}function getFieldOrDefault(e,t,r){let a=e[t];return null==a?r:a}async function loadTextFile(e){try{const t=cleanPath(e),r=await fetch("http://localhost:3001/generate-signed-url",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({dirUrl:t})});if(!r.ok)throw new Error(`Erreur lors de la génération de l'URL signée: ${r.status}`);const{url:a}=await r.json();console.log("Tentative de chargement du fichier texte depuis:",a);const n=await fetch(a);if(!n.ok)throw new Error(`Erreur lors du téléchargement du fichier: ${n.status}`);const s=await n.text();return console.log("Contenu du fichier texte chargé depuis",a,":",s),s}catch(t){throw console.error(`Erreur lors de la récupération du fichier texte depuis ${e}:`,t),t}}async function loadJSONFile(e){try{const t=cleanPath(e),r=await fetch("http://localhost:3001/generate-signed-url",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({dirUrl:t})});if(console.log("Chemin avant génération de l'URL signée:",t),!r.ok)throw new Error(`Erreur lors de la génération de l'URL signée: ${r.status}`);const{url:a}=await r.json();console.log("Tentative de chargement du fichier JSON depuis:",a);const n=await fetch(a);if(!n.ok)throw new Error(`Erreur lors du téléchargement du fichier JSON: ${n.status}`);const s=await n.json();return console.log("Contenu du fichier JSON chargé depuis",a,":",s),s}catch(t){throw console.error(`Erreur lors de la récupération du fichier JSON depuis ${e}:`,t),t}}function cleanPath(e){const t=e.split("/"),r=[];for(let e=0;e<t.length;e++)".."===t[e]?r.length&&r.pop():"."!==t[e]&&""!==t[e]&&r.push(t[e]);return r.join("/")}class Router{constructor(e,t){this.dirUrl=e,this.filenameToLink=t}translate(e){if(null!=this.filenameToLink)return this.filenameToLink[e];return`${this.cleanPath(this.dirUrl)}/${e}`}cleanPath(e){const t=e.split("/"),r=[];for(let e=0;e<t.length;e++)".."===t[e]?r.length&&r.pop():"."!==t[e]&&""!==t[e]&&r.push(t[e]);return r.join("/")}}const Format={RED:{numChannels:1},LUMINANCE_ALPHA:{numChannels:2},RGB:{numChannels:3},RGBA:{numChannels:4}},GridTextureSource={RGBA_FROM_RGBA:{format:Format.RGBA,channels:[0,1,2,3]},RGB_FROM_RGBA:{format:Format.RGBA,channels:[0,1,2]},RGB_FROM_RGB:{format:Format.RGB,channels:[0,1,2]},ALPHA_FROM_RGBA:{format:Format.RGBA,channels:[3]},RED_FROM_RED:{format:Format.RED,channels:[0]},LA_FROM_LUMINANCE_ALPHA:{format:Format.LUMINANCE_ALPHA,channels:[0,1]}},GridTextureDestination={RED_IN_RED:{format:Format.RED,channels:[0]},RGB_IN_RGB:{format:Format.RGB,channels:[0,1,2]},RGBA_IN_RGBA:{format:Format.RGBA,channels:[0,1,2,3]},LA_IN_LUMINANCE_ALPHA:{format:Format.LUMINANCE_ALPHA,channels:[0,1]},LUMINANCE_IN_LUMINANCE_ALPHA:{format:Format.LUMINANCE_ALPHA,channels:[0]},ALPHA_IN_LUMINANCE_ALPHA:{format:Format.LUMINANCE_ALPHA,channels:[1]}};let gSceneAccumulate=null,gLowResBlitCamera=null,gHighResBlitCamera=null,gOldMatrixWorld=null,gOldProjectionMatrix=null,gFrameIndex=0,gLowResTexture=null;function createAccumulateMaterial(e,t,r,a){return new THREE.ShaderMaterial({uniforms:{mapLowRes:{value:e},mapHistory:{value:t},lowResolution:{value:r},highResolution:{value:a},jitterOffset:{value:new THREE.Vector2(0,0)},emaAlpha:{value:.15}},vertexShader:accumulateVertexShader,fragmentShader:accumulateFragmentShader})}const gAccumulationTextures=[null,null],normalizeVertexShader="\nvarying vec2 vUv;\nvoid main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n",normalizeFragmentShader="\nvarying vec2 vUv;\nuniform sampler2D map;\nvoid main() {\n gl_FragColor = texture2D(map, vUv);\n if (gl_FragColor.a > 0.0) {\n gl_FragColor.rgb /= gl_FragColor.a;\n }\n gl_FragColor.a = 1.0;\n}\n";function createNormalizeMaterial(e){return new THREE.ShaderMaterial({uniforms:{map:{value:e}},vertexShader:normalizeVertexShader,fragmentShader:normalizeFragmentShader})}let gSceneNormalize=null;const accumulateVertexShader="\nvarying vec2 vUv;\nvoid main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n",accumulateFragmentShader="\nvarying vec2 vUv;\nuniform vec2 lowResolution;\nuniform vec2 highResolution;\nuniform vec2 jitterOffset;\nuniform float emaAlpha;\n\nuniform sampler2D mapLowRes;\nuniform sampler2D mapHistory;\n\nfloat pixelFilter(vec2 pixelCenter, vec2 sampleCenter) {\n vec2 delta = pixelCenter - sampleCenter;\n float squaredNorm = dot(delta, delta);\n return exp(-2.29 * squaredNorm);\n}\n\nvoid main() {\n // First we need to compute the coordinates of the pixel centers\n // in the low resolution grid by compensating for the camera jitter.\n // Note that the offset is defined in clip space [-1,1]^2, so we need\n // to multiply it by 0.5 to make it valid in texture space [0,1]^2.\n vec2 compensatedUnitCoords = vUv - jitterOffset * 0.5;\n\n // Now compute the integer coordinates in the low resolution grid for each\n // adjacent texel.\n ivec2 lowResCoords00 = ivec2(compensatedUnitCoords * lowResolution - 0.5);\n ivec2 lowResCoords01 = ivec2(0, 1) + lowResCoords00;\n ivec2 lowResCoords10 = ivec2(1, 0) + lowResCoords00;\n ivec2 lowResCoords11 = ivec2(1, 1) + lowResCoords00;\n\n float mask00 =\n min(lowResCoords00.x, lowResCoords00.y) < 0 ||\n lowResCoords00.x >= int(lowResolution.x) ||\n lowResCoords00.y >= int(lowResolution.y) ? 0.0 : 1.0;\n float mask01 =\n min(lowResCoords01.x, lowResCoords01.y) < 0 ||\n lowResCoords01.x >= int(lowResolution.x) ||\n lowResCoords01.y >= int(lowResolution.y) ? 0.0 : 1.0;\n float mask10 =\n min(lowResCoords10.x, lowResCoords10.y) < 0 ||\n lowResCoords10.x >= int(lowResolution.x) ||\n lowResCoords10.y >= int(lowResolution.y) ? 0.0 : 1.0;\n float mask11 =\n min(lowResCoords11.x, lowResCoords11.y) < 0 ||\n lowResCoords11.x >= int(lowResolution.x) ||\n lowResCoords11.y >= int(lowResolution.y) ? 0.0 : 1.0;\n\n // We also need to keep track of the high resolution counterparts of these\n // coordinates, so we can compute the pixel reconstruction filter weights.\n vec2 compensatedHighResCoords = highResolution * compensatedUnitCoords;\n vec2 highResCoords00 =\n highResolution * (vec2(lowResCoords00) + 0.5) / lowResolution;\n vec2 highResCoords01 =\n highResolution * (vec2(lowResCoords01) + 0.5) / lowResolution;\n vec2 highResCoords10 =\n highResolution * (vec2(lowResCoords10) + 0.5) / lowResolution;\n vec2 highResCoords11 =\n highResolution * (vec2(lowResCoords11) + 0.5) / lowResolution;\n\n vec4 lowResColor = vec4(0.0, 0.0, 0.0, 0.0);\n lowResColor += mask00 * vec4(\n texelFetch(mapLowRes,lowResCoords00, 0).rgb, 1.0) *\n pixelFilter(compensatedHighResCoords, highResCoords00);\n lowResColor += mask01 * vec4(\n texelFetch(mapLowRes, lowResCoords01, 0).rgb, 1.0) *\n pixelFilter(compensatedHighResCoords, highResCoords01);\n lowResColor += mask10 * vec4(\n texelFetch(mapLowRes, lowResCoords10, 0).rgb, 1.0) *\n pixelFilter(compensatedHighResCoords, highResCoords10);\n lowResColor += mask11 * vec4(\n texelFetch(mapLowRes, lowResCoords11, 0).rgb, 1.0) *\n pixelFilter(compensatedHighResCoords, highResCoords11);\n\n vec4 historyColor = texture2D(mapHistory, vUv);\n gl_FragColor = emaAlpha * lowResColor + (1.0 - emaAlpha) * historyColor;\n}\n";function setupProgressiveRendering(e,t){gHighResBlitCamera=new THREE.OrthographicCamera(e.offsetWidth/-2,e.offsetWidth/2,e.offsetHeight/2,e.offsetHeight/-2,-1e4,1e4),gHighResBlitCamera.position.z=100;let r=new THREE.PlaneBufferGeometry(e.offsetWidth,e.offsetHeight);gLowResTexture=new THREE.WebGLRenderTarget(Math.trunc(e.offsetWidth/t),Math.trunc(e.offsetHeight/t),{minFilter:THREE.NearestFilter,magFilter:THREE.NearestFilter,type:THREE.UnsignedByteType,format:THREE.RGBFormat}),gAccumulationTextures[0]=new THREE.WebGLRenderTarget(e.offsetWidth,e.offsetHeight,{minFilter:THREE.NearestFilter,magFilter:THREE.NearestFilter,type:THREE.FloatType,format:THREE.RGBAFormat}),gAccumulationTextures[1]=new THREE.WebGLRenderTarget(e.offsetWidth,e.offsetHeight,{minFilter:THREE.NearestFilter,magFilter:THREE.NearestFilter,type:THREE.FloatType,format:THREE.RGBAFormat});let a=new THREE.Mesh(r,createAccumulateMaterial(gLowResTexture.texture,gAccumulationTextures[1],new THREE.Vector2(Math.trunc(e.offsetWidth/t),Math.trunc(e.offsetHeight/t)),new THREE.Vector2(e.offsetWidth,e.offsetHeight)));a.position.z=-100,gSceneAccumulate=new THREE.Scene,gSceneAccumulate.add(a),gSceneAccumulate.autoUpdate=!1;let n=new THREE.Mesh(r,createNormalizeMaterial(gAccumulationTextures[0].texture));n.position.z=-100,gSceneNormalize=new THREE.Scene,gSceneNormalize.add(n),gSceneNormalize.autoUpdate=!1,gLowResBlitCamera=new THREE.OrthographicCamera(Math.trunc(e.offsetWidth/t)/-2,Math.trunc(e.offsetWidth/t)/2,Math.trunc(e.offsetHeight/t)/2,Math.trunc(e.offsetHeight/t)/-2,-1e4,1e4),gLowResBlitCamera.position.z=100,gOldProjectionMatrix=gCamera.projectionMatrix.clone(),gOldMatrixWorld=gCamera.matrixWorld.clone()}function renderFrame(e){e||(e=gCamera.projectionMatrix.clone());let t=new THREE.Matrix4;t.getInverse(e);let r=gCamera.matrixWorld;submodel_T_world=gSubmodelTransform,submodel_T_camera=new THREE.Matrix4,submodel_T_camera.multiplyMatrices(submodel_T_world,r);let a=getRayMarchScene();a.children[0].material.uniforms.world_T_cam.value=submodel_T_camera,a.children[0].material.uniforms.cam_T_clip.value=t,a.children[0].material.uniforms.displayMode.value=gDisplayMode-0,gRenderer.clear(),gRenderer.render(a,gLowResBlitCamera)}function renderProgressively(){const e=gAccumulationTextures[0].width/gLowResTexture.width;if(1==e)return void renderFrame();let t=!gCamera.projectionMatrix.equals(gOldProjectionMatrix)||!gCamera.matrixWorld.equals(gOldMatrixWorld);const r=e%2==0;let a=.5,n=Math.trunc(e/2);r||(a=.5,n+=1);let s=[],i=[];for(let t=0;t<n;t++)for(let r=0;r<n;r++)s.push((a+t)/e),i.push((a+r)/e),s.push(-(a+t)/e),i.push((a+r)/e),s.push((a+t)/e),i.push(-(a+r)/e),s.push(-(a+t)/e),i.push(-(a+r)/e);let o=gFrameIndex%s.length,l=s[o],c=i[o];gLowResBlitCamera.left=l+gLowResTexture.width/-2,gLowResBlitCamera.right=l+gLowResTexture.width/2,gLowResBlitCamera.top=c+gLowResTexture.height/2,gLowResBlitCamera.bottom=c+gLowResTexture.height/-2,gLowResBlitCamera.updateProjectionMatrix(),l*=2/gLowResTexture.width,c*=2/gLowResTexture.height;let u=gCamera.projectionMatrix.clone();u.elements[8]+=l,u.elements[9]+=c,gRenderer.setRenderTarget(gLowResTexture),renderFrame(u);let d=Math.min(1,.7/s.length);t&&(gFrameIndex=0,d=1);let p=gFrameIndex%2,g=1-p;gRenderer.setRenderTarget(gAccumulationTextures[p]),gSceneAccumulate.children[0].material.uniforms.mapHistory.value=gAccumulationTextures[g].texture,gSceneAccumulate.children[0].material.uniforms.jitterOffset.value=new THREE.Vector2(l,c),gSceneAccumulate.children[0].material.uniforms.emaAlpha.value=d,gRenderer.clear(),gRenderer.render(gSceneAccumulate,gHighResBlitCamera),gRenderer.setRenderTarget(null),gSceneNormalize.children[0].material.uniforms.map.value=gAccumulationTextures[p].texture,gRenderer.clear(),gRenderer.render(gSceneNormalize,gHighResBlitCamera),gFrameIndex++,gOldProjectionMatrix=gCamera.projectionMatrix.clone(),gOldMatrixWorld=gCamera.matrixWorld.clone()}function computeTrilerpLocationsAndWeights(e,t,r){let a=(new THREE.Vector3).copy(e);a.addScalar(1),a.divideScalar(2),a.multiplyScalar(r),a.subScalar(.5);const n=(new THREE.Vector3).copy(a).floor(),s=(new THREE.Vector3).copy(a).ceil();let i=t.x>0?s.x:n.x,o=t.y>0?s.y:n.y,l=t.z>0?s.z:n.z;i=Math.min(Math.max(i,0),r-1),o=Math.min(Math.max(o,0),r-1),l=Math.min(Math.max(l,0),r-1),i=r-1-i,[o,l]=[l,o];const c=(l*r+o)*r+i;let u=a.x-n.x,d=a.y-n.y,p=a.z-n.z;0==t.x&&(u=1-u),0==t.y&&(d=1-d),0==t.z&&(p=1-p);return[c,u*d*p]}function trilerpDeferredMlpKernel(e,t,r){let a,n,s;if(gDeferredMlp["ResampleDense_"+t+"/kernel"]){const i=gDeferredMlp["ResampleDense_"+t+"/kernel"],o=i.data,l=i.shape[1],c=i.shape[4],u=i.shape[5];a=makeMultipleOf(u,4),n=makeMultipleOf(c,4),s=new Float32Array(n*a);let d=(new THREE.Vector3).copy(r);d.divideScalar(getSubmodelScaleFactor(e));const p=e*l*l*l*c*u;for(let e=0;e<2;e++)for(let t=0;t<2;t++)for(let r=0;r<2;r++){const[i,g]=computeTrilerpLocationsAndWeights(d,new THREE.Vector3(e,t,r),l),m=p+c*u*i;for(let i=0;i<a;i++)for(let a=0;a<n;a++){let l=i*n+a,d=0;a<c&&i<u&&(d=o[m+a*u+i]),e+t+r===0?s[l]=g*d:s[l]+=g*d}}}else{const e=gDeferredMlp["Dense_"+t+"/kernel"],r=e.data,i=e.shape[0],o=e.shape[1];a=makeMultipleOf(o,4),n=makeMultipleOf(i,4),s=new Float32Array(n*a);for(let e=0;e<a;e++)for(let t=0;t<n;t++){t<i&&e<o&&(s[e*n+t]=r[t*o+e])}}let i=new Float32Array(n*a);for(let e=0;e<n;e+=4)for(let t=0;t<a;t++)for(let r=0;r<4;r++)i[e/4*a*4+4*t+r]=s[e/4*4+t*(n/4*4)+r];let o=new THREE.DataTexture(i,1,n*a/4,THREE.RGBAFormat);return o.magFilter=THREE.NearestFilter,o.minFilter=THREE.NearestFilter,o.type=THREE.FloatType,o}function trilerpDeferredMlpBiases(e,t,r){let a;if(gDeferredMlp["ResampleDense_"+t+"/bias"]){const n=gDeferredMlp["ResampleDense_"+t+"/bias"],s=n.data,i=n.shape[1],o=n.shape[4],l=makeMultipleOf(o,4);a=new Array(l/4);let c=(new THREE.Vector3).copy(r);c.divideScalar(getSubmodelScaleFactor(e));const u=e*i*i*i*o;for(let e=0;e<2;e++)for(let t=0;t<2;t++)for(let r=0;r<2;r++){const[n,d]=computeTrilerpLocationsAndWeights(c,new THREE.Vector3(e,t,r),i),p=u+o*n;for(let n=0;n<l/4;++n){let i=new THREE.Vector4(0,0,0,0);for(let e=0;e<4;e++)4*n+0<l&&i.setComponent(e,s[p+4*n+e]);i.multiplyScalar(d),e+t+r===0?a[n]=i:a[n].add(i)}}}else{const e=gDeferredMlp["Dense_"+t+"/bias"],r=e.data,n=makeMultipleOf(e.shape[0],4);a=new Array(n/4);for(let e=0;e<n/4;++e){let t=new THREE.Vector4(0,0,0,0);for(let a=0;a<4;a++)4*e+0<n&&t.setComponent(a,r[4*e+a]);a[e]=t}}return a}function rewriteViewDependenceDefinitions(e,t){let r=getDeferredMlp();const a=r["ResampleDense_0/kernel"]?"ResampleDense_":"Dense_",n=r["ResampleDense_0/kernel"]?4:0;let s=t,i=["intermediate_one","intermediate_two","result"];for(let e=0;e<3;e++){let t=r[a+e+"/bias"].shape[n],o=`bias_${e}`,l=i[e],c=[];for(let e=0;e<t/4;e++)c.push(`${l}[${e}] = ${o}[${e}];`);let u=c.join(" ")+"\n";s=s.replace(new RegExp(`INITIALIZE_OUTPUT_ACTIVATIONS_${e}`,"g"),u)}let o=makeMultipleOf(r[a+"0/kernel"].shape[n],4),l=makeMultipleOf(r[a+"0/bias"].shape[n],4),c=makeMultipleOf(r[a+"1/bias"].shape[n],4),u=makeMultipleOf(r[a+"2/bias"].shape[n],4);return s=s.replace(new RegExp("NUM_CHANNELS_ZERO","g"),o),s=s.replace(new RegExp("NUM_POSENC_SCALES","g"),4..toString()),s=s.replace(new RegExp("NUM_CHANNELS_ONE","g"),l),s=s.replace(new RegExp("NUM_CHANNELS_TWO","g"),c),s=s.replace(new RegExp("NUM_CHANNELS_THREE","g"),u),s}function makeMultipleOf(e,t){return e%t==0?e:e+t-e%t}function setupInitialCameraPose(e,t){function r(e){var r,a,n;gCamera.position.x=e.position[0]+t.x,gCamera.position.y=e.position[1]+t.y,gCamera.position.z=e.position[2]+t.z,r=e.lookat[0]+t.x,a=e.lookat[1]+t.y,n=e.lookat[2]+t.z,gOrbitControls?(gOrbitControls.target.x=r,gOrbitControls.target.y=a,gOrbitControls.target.z=n):gMapControls?(gMapControls.target.x=gCamera.position.x+(r-gCamera.position.x)*gCamera.near,gMapControls.target.y=gCamera.position.y+(a-gCamera.position.y)*gCamera.near,gMapControls.target.z=gCamera.position.z+(n-gCamera.position.z)*gCamera.near):gCamera.lookAt(r,a,n)}initialPoses={default:{position:[0,0,0],lookat:[0,0,1]},gardenvase:{position:[-1.1868985500525444,.1898527233835131,-.04923970470097733],lookat:[-.05581392405861873,-.40202760746449473,.02985343723310108]},stump:{position:[0,.4,-.8],lookat:[0,-.3,0]},flowerbed:{position:[-.02402388218043944,.11825367482140309,.907525093384825],lookat:[.016306507293821822,-.15676691106539536,-.016192691610482132]},treehill:{position:[-.70994804046872,.19435986647308223,.30833533637897453],lookat:[.06327294888291587,-.13299740290200024,.0037554887097183934]},bicycle:{position:[-.4636408064933045,.49624791762954734,.8457540259646037],lookat:[.017170160491904368,-.24649043500978007,-.07787524806850904]},kitchenlego:{position:[-.5872864419408019,.05633623000443683,-.9472239198227385],lookat:[.07177184299031553,-.4020277194862108,.04850453170234236]},fulllivingroom:{position:[1.1539572663654272,-.006785278327404387,-.0972986385811351],lookat:[-.05581392405861873,-.40202760746449473,.02985343723310108]},kitchencounter:{position:[-.7006764413546107,.2255633917824672,-.46941182833135847],lookat:[.13197415755218864,-.4020278046227117,.09221809216932579]},officebonsai:{position:[-.4773314920559294,.05409730603092788,1.014304107335418],lookat:[.11970974858222336,-.40426664345968033,-.019801655674420764]}},r(initialPoses.default);for(let t in initialPoses)if(e.includes(t)){r(initialPoses[t]);break}gCamera.updateProjectionMatrix()}let gOrbitControls=null,gMapControls=null,gPointerLockControls=null,gKeyW=!1,gKeyA=!1,gKeyS=!1,gKeyD=!1,gKeyQ=!1,gKeyE=!1,gKeyShift=!1;const gClock=new THREE.Clock;function addHandlers(){let e=document.getElementById("shader-editor");document.addEventListener("keypress",(function(t){if("input"!==document.activeElement.tagName.toLowerCase()&&"textarea"!==document.activeElement.tagName.toLowerCase()&&document.activeElement!==e){if(32!==t.keyCode&&" "!==t.key&&"Spacebar"!==t.key||(gDisplayMode==DisplayModeType.DISPLAY_NORMAL?(gDisplayMode=DisplayModeType.DISPLAY_DIFFUSE,console.log("Displaying DIFFUSE")):gDisplayMode==DisplayModeType.DISPLAY_DIFFUSE?(gDisplayMode=DisplayModeType.DISPLAY_FEATURES,console.log("Displaying DISPLAY_FEATURES")):gDisplayMode==DisplayModeType.DISPLAY_FEATURES?(gDisplayMode=DisplayModeType.DISPLAY_VIEW_DEPENDENT,console.log("Displaying DISPLAY_VIEW_DEPENDENT")):gDisplayMode==DisplayModeType.DISPLAY_VIEW_DEPENDENT?(gDisplayMode=DisplayModeType.DISPLAY_COARSE_GRID,console.log("Displaying DISPLAY_COARSE_GRID")):(gDisplayMode=DisplayModeType.DISPLAY_NORMAL,console.log("Displaying DISPLAY_NORMAL")),t.preventDefault()),"r"===t.key){console.log("Recompile shader.");let r=getRayMarchScene().children[0].material;r.fragmentShader=e.value,r.needsUpdate=!0,t.preventDefault()}if("?"===t.key){let e=gCamera.getWorldPosition(new THREE.Vector3(0,0,0)),r=gCamera.getWorldQuaternion(new THREE.Quaternion);console.log(`\n// Camera Info:\ngCamera.position.set(${e.x}, ${e.y}, ${e.z});\ngCamera.quaternion.set(${r.x}, ${r.y}, ${r.z}, ${r.w});\n`),t.preventDefault()}}})),document.addEventListener("keydown",(function(t){if("input"===document.activeElement.tagName.toLowerCase()||"textarea"===document.activeElement.tagName.toLowerCase())return;if(document.activeElement===e)return;let r=t.key.toLowerCase();"w"===r&&(gKeyW=!0,t.preventDefault()),"a"===r&&(gKeyA=!0),"s"===r&&(gKeyS=!0,t.preventDefault()),"d"===r&&(gKeyD=!0,t.preventDefault()),"q"===r&&(gKeyQ=!0,t.preventDefault()),"e"===r&&(gKeyE=!0,t.preventDefault()),"Shift"===t.key&&(gKeyShift=!0,t.preventDefault())})),document.addEventListener("keyup",(function(t){if("input"===document.activeElement.tagName.toLowerCase()||"textarea"===document.activeElement.tagName.toLowerCase())return;if(document.activeElement===e)return;let r=t.key.toLowerCase();"w"===r&&(gKeyW=!1,t.preventDefault()),"a"===r&&(gKeyA=!1),"s"===r&&(gKeyS=!1,t.preventDefault()),"d"===r&&(gKeyD=!1,t.preventDefault()),"q"===r&&(gKeyQ=!1,t.preventDefault()),"e"===r&&(gKeyE=!1,t.preventDefault()),"Shift"===t.key&&(gKeyShift=!1,t.preventDefault())}))}function setupCameraControls(e,t){if(e&&"fps"==e){gPointerLockControls=new THREE.PointerLockControls(gCamera,t);let e=document.createElement("button");e.innerHTML="Commencer la visite !",e.classList.add("mouse-navigation-button"),e.addEventListener("click",(function(){gPointerLockControls.lock(),gPointerLockControls.connect(),e.classList.add("hidden")}),!1),gPointerLockControls.addEventListener("unlock",(function(){e.classList.remove("hidden")})),t.appendChild(e)}else e&&"map"==e?(gMapControls=new THREE.OrbitControls(gCamera,t),gMapControls.panSpeed=.5/gCamera.near,gMapControls.enableZoom=!1,gMapControls.screenSpacePanning=!1,gMapControls.mouseButtons={LEFT:THREE.MOUSE.ROTATE,RIGHT:THREE.MOUSE.PAN},gMapControls.touches={ONE:THREE.TOUCH.PAN,TWO:THREE.TOUCH.DOLLY_ROTATE}):(gOrbitControls=new THREE.OrbitControls(gCamera,t),gOrbitControls.screenSpacePanning=!0,gOrbitControls.zoomSpeed=.5)}function updateCameraControls(){if(gOrbitControls)gOrbitControls.update();else if(gMapControls)gMapControls.update();else if(gPointerLockControls){const e=gClock.getDelta();let t=.25;gKeyShift&&(t=1);let r=gCamera.getWorldDirection(new THREE.Vector3(0,0,0)),a=new THREE.Vector3(0,1,0);gKeyW&&(gCamera.position=gCamera.position.addScaledVector(r,e*t)),gKeyA&&gPointerLockControls.moveRight(-e*t),gKeyS&&(gCamera.position=gCamera.position.addScaledVector(r,-e*t)),gKeyD&&gPointerLockControls.moveRight(e*t),gKeyQ&&(gCamera.position=gCamera.position.addScaledVector(a,-e*t)),gKeyE&&(gCamera.position=gCamera.position.addScaledVector(a,e*t))}}let gIsCoolingDown=!1,gBenchmarkTimestamps=null,gFrameTimes=[],gBenchmarkCameras={},gBenchmarkCameraIndex=0;const gBenchmarkMethodName="blockmerf";let gBenchmarkSceneName=null,gSaveBenchmarkFrames=!1;function setupBenchmarkStats(e,t){gBenchmarkSceneName=e,gSaveBenchmarkFrames=t;let r=document.getElementById("benchmark-stats");r.style.display="block",r.addEventListener("click",(e=>{gBenchmark=!0}))}function clearBenchmarkStats(e){document.getElementById("benchmark-stats").innerHTML=""}function addBenchmarkRow(e){document.getElementById("benchmark-stats").innerHTML+=e+"\n"}function getBenchmarkStats(e){return document.getElementById("benchmark-stats").innerHTML}function loadBenchmarkCameras(e){const t=e.translate("test_frames.json"),r=loadJSONFile(t);r.catch((e=>{console.error("Could not load test frames from: "+t+", error: "+e)})),r.then((e=>{gBenchmarkCameras=e.test_frames}))}function setBenchmarkCameraPose(e,t){e.position.fromArray(gBenchmarkCameras[t].position),e.setRotationFromMatrix((new THREE.Matrix4).fromArray(gBenchmarkCameras[t].rotation)),e.projectionMatrix.fromArray(gBenchmarkCameras[t].projection)}function cooldownFrame(e){const t=.5*(1+Math.sin(e*Math.PI/1e3));let r=new THREE.Color("#FFFFFF");r.lerp(new THREE.Color("#A5C0E2"),t),gRenderer.setClearColor(r,1),gRenderer.clear(),gStats&&gStats.update(),gIsCoolingDown&&requestAnimationFrame(cooldownFrame)}function formatTimestampAsString(){const e=new Date,t=e.getHours().toString().padStart(2,"0"),r=e.getMinutes().toString().padStart(2,"0");return`${e.getFullYear()}_${e.getMonth()+1}_${e.getDate()}_${t}${r}`}function benchmarkPerformance(e){const t=Math.max(4,Math.ceil(100/gFrameMult)),r=Math.max(2,Math.ceil(.1*t));if(isLoading())return e;if(!gBenchmarkTimestamps&&!gIsCoolingDown){setBenchmarkCameraPose(gCamera,0),gBenchmarkTimestamps=[];let t=new THREE.Vector2;return gRenderer.getSize(t),clearBenchmarkStats(),addBenchmarkRow(`frame timestamps (ms) at ${t.x}x${t.y}`),addBenchmarkRow("cam_idx ; start ; end ; mean frame time"),e}if(gBenchmarkTimestamps.push(window.performance.now()),gBenchmarkTimestamps.length<t)return e;gSaveBenchmarkFrames&&(frameAsPng=gRenderer.domElement.toDataURL("image/png"),saveAs(frameAsPng,digits(gBenchmarkCameraIndex,4)+".png"));let a=gBenchmarkTimestamps.slice(r);const n=a.length,s=a[0],i=a.pop();let o=(i-s)/(gFrameMult*(n-1));if(gFrameTimes.push(o),addBenchmarkRow(`${gBenchmarkCameraIndex} ; ${s} ; ${i} ; ${o}`),++gBenchmarkCameraIndex>=gBenchmarkCameras.length){console.log(gFrameTimes.reduce(((e,t)=>e+t),0)/gFrameTimes.length),gBenchmark=!1;const t=new Blob([getBenchmarkStats()],{type:"text/plain;charset=utf-8"}),r="blockmerf_"+gBenchmarkSceneName+"_frameMult_"+gFrameMult+"_"+formatTimestampAsString()+".csv";return saveAs(t,r),e}return gBenchmarkTimestamps=[],setBenchmarkCameraPose(gCamera,gBenchmarkCameraIndex),e}let gSubmodelPanel=null,gVMemPanel=null,gStepMult=1,gExposure=null;function loadScene(e,t){let r;e&&e.includes(".json")?r=loadJSONFile(e):(r=Promise.resolve(null),console.error("dirUrl est null ou non valide. Le fichier Json est dans le dossier")),r.then((r=>{const a=new Router(e,r);console.log("router:",a);const n=a.translate("scene_params.json");console.log("sceneParamsUrl:",n);const s=loadJSONFile(n);return console.log("sceneParamsPromise:",s),t.loadBenchmarkCameras&&loadBenchmarkCameras(a),Promise.all([s,{router:a,filenameToLink:r}])})).then((e=>{const[t,r]=e;let a=0;gUseSubmodel=t.hasOwnProperty("num_local_submodels")&&t.num_local_submodels>1,gUseSubmodel&&(gSubmodelCount=t.num_local_submodels,a=t.sm_to_params[t.submodel_idx]);let n=[];for(let e=0;e<gSubmodelCount;++e){const a=t.params_to_sm[e],s=r.router.translate(submodelAssetPath(a,"scene_params.json"));n.push(loadJSONFile(s))}return Promise.all([{...r,initialSubmodelIndex:a},...n])})).then((r=>{let[a,...n]=r;for(let r=0;r<n.length;++r){n[r]=extend(n[r],t);const s=n[r].params_to_sm[r];let i=e;gUseSubmodel&&(i=`${i}/${submodelAssetPath(s)}`);let o=new Router(i,a.filenameToLink),l=initializeSceneContent(n[r],o);console.log(`spec for submodel #${r}:`,l.spec),registerSubmodelContent(r,l)}let s=a.initialSubmodelIndex;return setupInitialCameraPose(e,submodelCenter(s,getSubmodelContent(s).params)),Promise.all([s,initializeDeferredMlp(s)])})).then((([e,t])=>initializePingPongBuffers(e))).then((()=>requestAnimationFrame(renderNextFrame)))}let disableCameraControls=!1;function initFromParameters(){const e=new URL(window.location.href).searchParams;console.log(e);const t="nyc/sm_004";console.log(t);let r=e.get("quality"),a=parseInt(e.get("downscale")||1,10);const n=e.get("stepMult");n&&(gStepMult=parseInt(n,10));const s=e.get("frameMult");s&&(gFrameMult=parseInt(s,10));const i=e.get("exposure");i&&(gExposure=parseFloat(i));let o={};const l=e.get("benchmark");if(l&&("time"===l.toLowerCase()||"quality"===l.toLowerCase())){o.loadBenchmarkCameras=!0,r="high";const e=t.split("/").slice(-2);setupBenchmarkStats(e[0]+"_"+e[1],"quality"===l.toLowerCase())}const c=e.get("deferredMode");c&&(o.deferred_rendering_mode=c);const u=e.get("combineMode");u&&"concat_and_sum"===u&&(o.merge_features_combine_op="coarse_sum");const d=e.get("useBits");d&&(o.useBits="true"===d.toLowerCase());const p=e.get("useDistanceGrid");p&&(o.useDistanceGrid="true"===p.toLowerCase());const g=e.get("legacyGrids");g&&(o.legacyGrids="true"===g.toLowerCase());const m=e.get("activation");m&&(o.activation=m);const h=e.get("featureGating");h&&(o.feature_gating="true"===h.toLowerCase());const f=e.get("submodelCacheSize");f&&(gSubmodelCacheSize=Number(f));const y=e.get("mergeSlices");y&&(o.merge_slices="true"==y);const _=e.get("backgroundColor");_&&(o.backgroundColor="#"+_);const T=document.createElement("div");T.classList.add("view");document.getElementById("viewspacecontainer").appendChild(T);const{width:x,height:S}=function(e){const t=getComputedStyle(e);return{width:parseInt(t.width,10),height:parseInt(t.height,10)}}(T);T.style.width=`${x}px`,T.style.height=`${S}px`,console.log("Width:",x,"Height:",S);const R=e.get("mouseMode")||"orbit";let E=.99;if(!e.get("downscale")&&r){let e=x*S;for("phone"==r?(e=135e3,E=.8):"low"==r?(e=15e4,E=.8):"medium"==r&&(e=768e3,E=.95);x*S/a>e;)a++;console.log("Automatically chose a downscaling factor of "+a)}o.useLargerStepsWhenOccluded=!1,o.step_size_visibility_delay=E;const b=parseFloat(e.get("near")||.01),C=parseFloat(e.get("vfovy")||40),w=document.querySelector(".viewspace");w.textContent="",w.appendChild(T);let A=document.createElement("canvas");T.appendChild(A),A.style.width="100%",A.style.height="100%",A.style.border=getComputedStyle(T).border,A.style.borderRadius=getComputedStyle(T).borderRadius,A.style.boxSizing=getComputedStyle(T).boxSizing,gStats=Stats(),gStats.dom.style.position="absolute",gStats.dom.style.display="none",w.appendChild(gStats.dom),gSubmodelPanel=gStats.addPanel(new Stats.Panel("SM","#0ff","#002")),gSubmodelPanel.update(getActiveSubmodelIndex()),gVMemPanel=gStats.addPanel(new Stats.Panel("MB VRAM","#0ff","#002")),gVMemPanel.update(0),gStats.showPanel(0);let v=A.getContext("webgl2",{powerPreference:"high-performance",alpha:!1,stencil:!0,precision:"highp",depth:!0,antialias:!1,desynchronized:!1,preserveDrawingBuffer:l&&"quality"===l.toLowerCase()});v.enable(v.DEPTH_TEST),v.depthFunc(v.LEQUAL),v.pixelStorei(v.UNPACK_ALIGNMENT,1),v.viewport(0,0,A.width,A.height),gRenderer=new THREE.WebGLRenderer({canvas:A,context:v}),gCamera=new THREE.PerspectiveCamera(C,Math.trunc(T.offsetWidth/a)/Math.trunc(T.offsetHeight/a),b,2e3),gCamera.updateProjectionMatrix(),window.sceneCamera=gCamera,setupProgressiveRendering(T,a),gRenderer.autoClear=!1,gRenderer.setSize(T.offsetWidth,T.offsetHeight),gRenderer.setClearColor(0,1),setupCameraControls(R,T),setupViewport(Math.trunc(T.offsetWidth/a),Math.trunc(T.offsetHeight/a)),loadScene(t,o)}let sphereAdded=!1;function renderNextFrame(e){garbageCollectSubmodelPayloads();let t=positionToSubmodel(gCamera.position,getActiveSubmodelContent().params);setCurrentRayMarchScene(t),t=getActiveSubmodelIndex();let r=getSubmodelContent(t).params;for(let e=0;e<gFrameMult;++e){gSubmodelTransform=submodelTransform(t,r),gSubmodelPanel.update(t),gVMemPanel.update(getCurrentTextureUsageInBytes()/1e6),disableCameraControls||updateCameraControls(),gBenchmark||gCamera.updateProjectionMatrix(),gCamera.updateMatrixWorld();const e=submodelCenter(t,r),a=getSubmodelScale(t);let n=(new THREE.Vector3).copy(gCamera.position);n.sub(e),n.multiplyScalar(a);let s=getRayMarchScene().children[0].material.uniforms;s.weightsZero.value&&s.weightsZero.value.dispose(),s.weightsOne.value&&s.weightsOne.value.dispose(),s.weightsTwo.value&&s.weightsTwo.value.dispose(),s.bias_0.value=trilerpDeferredMlpBiases(t,0,n),s.bias_1.value=trilerpDeferredMlpBiases(t,1,n),s.bias_2.value=trilerpDeferredMlpBiases(t,2,n),s.weightsZero.value=trilerpDeferredMlpKernel(t,0,n),s.weightsOne.value=trilerpDeferredMlpKernel(t,1,n),s.weightsTwo.value=trilerpDeferredMlpKernel(t,2,n),gRenderer.clear(),renderProgressively(),gRenderer.render(gSphereScene,gCamera)}gStats.update();let a=()=>{requestAnimationFrame(renderNextFrame)};gBenchmark&&(a=benchmarkPerformance(a)),a()}function start(){initFromParameters(),addHandlers(),gCamera&&gRenderer?(addInteractionPlane(),setupNewPlaneGizmo(newPlane),setupMouseHover(),window.addEventListener("mousemove",onMouseMove,!1),window.addEventListener("mousedown",onMouseDown,!1),window.addEventListener("mouseup",onMouseUp,!1)):console.error("gCamera ou gRenderer non initialisés.")}window.onload=start;
.history/combined.min_20241120000008.js ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ //# sourceMappingURL=combined.min.js.map
2
+
3
+ let DecodeStream=function(){function e(){this.pos=0,this.bufferLength=0,this.eof=!1,this.buffer=null}return e.prototype={ensureBuffer:function(e){var t=this.buffer,r=t?t.byteLength:0;if(e<r)return t;for(var a=512;a<e;)a<<=1;for(var n=new Uint8Array(a),s=0;s<r;++s)n[s]=t[s];return this.buffer=n},getByte:function(){for(var e=this.pos;this.bufferLength<=e;){if(this.eof)return null;this.readBlock()}return this.buffer[this.pos++]},getBytes:function(e){var t=this.pos;if(e){this.ensureBuffer(t+e);for(var r=t+e;!this.eof&&this.bufferLength<r;)this.readBlock();var a=this.bufferLength;r>a&&(r=a)}else{for(;!this.eof;)this.readBlock();r=this.bufferLength}return this.pos=r,this.buffer.subarray(t,r)},lookChar:function(){for(var e=this.pos;this.bufferLength<=e;){if(this.eof)return null;this.readBlock()}return String.fromCharCode(this.buffer[this.pos])},getChar:function(){for(var e=this.pos;this.bufferLength<=e;){if(this.eof)return null;this.readBlock()}return String.fromCharCode(this.buffer[this.pos++])},makeSubStream:function(e,t,r){for(var a=e+t;this.bufferLength<=a&&!this.eof;)this.readBlock();return new Stream(this.buffer,e,t,r)},skip:function(e){e||(e=1),this.pos+=e},reset:function(){this.pos=0}},e}(),FlateStream=function(){var e=new Uint32Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),t=new Uint32Array([3,4,5,6,7,8,9,10,65547,65549,65551,65553,131091,131095,131099,131103,196643,196651,196659,196667,262211,262227,262243,262259,327811,327843,327875,327907,258,258,258]),r=new Uint32Array([1,2,3,4,65541,65543,131081,131085,196625,196633,262177,262193,327745,327777,393345,393409,459009,459137,524801,525057,590849,591361,657409,658433,724993,727041,794625,798721,868353,876545]),a=[new Uint32Array([459008,524368,524304,524568,459024,524400,524336,590016,459016,524384,524320,589984,524288,524416,524352,590048,459012,524376,524312,589968,459028,524408,524344,590032,459020,524392,524328,59e4,524296,524424,524360,590064,459010,524372,524308,524572,459026,524404,524340,590024,459018,524388,524324,589992,524292,524420,524356,590056,459014,524380,524316,589976,459030,524412,524348,590040,459022,524396,524332,590008,524300,524428,524364,590072,459009,524370,524306,524570,459025,524402,524338,590020,459017,524386,524322,589988,524290,524418,524354,590052,459013,524378,524314,589972,459029,524410,524346,590036,459021,524394,524330,590004,524298,524426,524362,590068,459011,524374,524310,524574,459027,524406,524342,590028,459019,524390,524326,589996,524294,524422,524358,590060,459015,524382,524318,589980,459031,524414,524350,590044,459023,524398,524334,590012,524302,524430,524366,590076,459008,524369,524305,524569,459024,524401,524337,590018,459016,524385,524321,589986,524289,524417,524353,590050,459012,524377,524313,589970,459028,524409,524345,590034,459020,524393,524329,590002,524297,524425,524361,590066,459010,524373,524309,524573,459026,524405,524341,590026,459018,524389,524325,589994,524293,524421,524357,590058,459014,524381,524317,589978,459030,524413,524349,590042,459022,524397,524333,590010,524301,524429,524365,590074,459009,524371,524307,524571,459025,524403,524339,590022,459017,524387,524323,589990,524291,524419,524355,590054,459013,524379,524315,589974,459029,524411,524347,590038,459021,524395,524331,590006,524299,524427,524363,590070,459011,524375,524311,524575,459027,524407,524343,590030,459019,524391,524327,589998,524295,524423,524359,590062,459015,524383,524319,589982,459031,524415,524351,590046,459023,524399,524335,590014,524303,524431,524367,590078,459008,524368,524304,524568,459024,524400,524336,590017,459016,524384,524320,589985,524288,524416,524352,590049,459012,524376,524312,589969,459028,524408,524344,590033,459020,524392,524328,590001,524296,524424,524360,590065,459010,524372,524308,524572,459026,524404,524340,590025,459018,524388,524324,589993,524292,524420,524356,590057,459014,524380,524316,589977,459030,524412,524348,590041,459022,524396,524332,590009,524300,524428,524364,590073,459009,524370,524306,524570,459025,524402,524338,590021,459017,524386,524322,589989,524290,524418,524354,590053,459013,524378,524314,589973,459029,524410,524346,590037,459021,524394,524330,590005,524298,524426,524362,590069,459011,524374,524310,524574,459027,524406,524342,590029,459019,524390,524326,589997,524294,524422,524358,590061,459015,524382,524318,589981,459031,524414,524350,590045,459023,524398,524334,590013,524302,524430,524366,590077,459008,524369,524305,524569,459024,524401,524337,590019,459016,524385,524321,589987,524289,524417,524353,590051,459012,524377,524313,589971,459028,524409,524345,590035,459020,524393,524329,590003,524297,524425,524361,590067,459010,524373,524309,524573,459026,524405,524341,590027,459018,524389,524325,589995,524293,524421,524357,590059,459014,524381,524317,589979,459030,524413,524349,590043,459022,524397,524333,590011,524301,524429,524365,590075,459009,524371,524307,524571,459025,524403,524339,590023,459017,524387,524323,589991,524291,524419,524355,590055,459013,524379,524315,589975,459029,524411,524347,590039,459021,524395,524331,590007,524299,524427,524363,590071,459011,524375,524311,524575,459027,524407,524343,590031,459019,524391,524327,589999,524295,524423,524359,590063,459015,524383,524319,589983,459031,524415,524351,590047,459023,524399,524335,590015,524303,524431,524367,590079]),9],n=[new Uint32Array([327680,327696,327688,327704,327684,327700,327692,327708,327682,327698,327690,327706,327686,327702,327694,0,327681,327697,327689,327705,327685,327701,327693,327709,327683,327699,327691,327707,327687,327703,327695,0]),5];function s(e){throw new Error(e)}function i(e){var t=0,r=e[t++],a=e[t++];-1!=r&&-1!=a||s("Invalid header in flate stream"),8!=(15&r)&&s("Unknown compression method in flate stream"),((r<<8)+a)%31!=0&&s("Bad FCHECK in flate stream"),32&a&&s("FDICT bit set in flate stream"),this.bytes=e,this.bytesPos=2,this.codeSize=0,this.codeBuf=0,DecodeStream.call(this)}return i.prototype=Object.create(DecodeStream.prototype),i.prototype.getBits=function(e){for(var t,r=this.codeSize,a=this.codeBuf,n=this.bytes,i=this.bytesPos;r<e;)void 0===(t=n[i++])&&s("Bad encoding in flate stream"),a|=t<<r,r+=8;return t=a&(1<<e)-1,this.codeBuf=a>>e,this.codeSize=r-=e,this.bytesPos=i,t},i.prototype.getCode=function(e){for(var t=e[0],r=e[1],a=this.codeSize,n=this.codeBuf,i=this.bytes,o=this.bytesPos;a<r;){var l;void 0===(l=i[o++])&&s("Bad encoding in flate stream"),n|=l<<a,a+=8}var c=t[n&(1<<r)-1],u=c>>16,d=65535&c;return(0==a||a<u||0==u)&&s("Bad encoding in flate stream"),this.codeBuf=n>>u,this.codeSize=a-u,this.bytesPos=o,d},i.prototype.generateHuffmanTable=function(e){for(var t=e.length,r=0,a=0;a<t;++a)e[a]>r&&(r=e[a]);for(var n=1<<r,s=new Uint32Array(n),i=1,o=0,l=2;i<=r;++i,o<<=1,l<<=1)for(var c=0;c<t;++c)if(e[c]==i){var u=0,d=o;for(a=0;a<i;++a)u=u<<1|1&d,d>>=1;for(a=u;a<n;a+=l)s[a]=i<<16|c;++o}return[s,r]},i.prototype.readBlock=function(){function i(e,t,r,a,n){for(var s=e.getBits(r)+a;s-- >0;)t[m++]=n}var o=this.getBits(3);if(1&o&&(this.eof=!0),0!=(o>>=1)){var l,c;if(1==o)l=a,c=n;else if(2==o){for(var u=this.getBits(5)+257,d=this.getBits(5)+1,p=this.getBits(4)+4,g=Array(e.length),m=0;m<p;)g[e[m++]]=this.getBits(3);for(var h=this.generateHuffmanTable(g),f=0,y=(m=0,u+d),_=new Array(y);m<y;){var T=this.getCode(h);16==T?i(this,_,2,3,f):17==T?i(this,_,3,3,f=0):18==T?i(this,_,7,11,f=0):_[m++]=f=T}l=this.generateHuffmanTable(_.slice(0,u)),c=this.generateHuffmanTable(_.slice(u,y))}else s("Unknown block type in flate stream");for(var x=(M=this.buffer)?M.length:0,S=this.bufferLength;;){var R=this.getCode(l);if(R<256)S+1>=x&&(x=(M=this.ensureBuffer(S+1)).length),M[S++]=R;else{if(256==R)return void(this.bufferLength=S);var E=(R=t[R-=257])>>16;E>0&&(E=this.getBits(E));f=(65535&R)+E;R=this.getCode(c),(E=(R=r[R])>>16)>0&&(E=this.getBits(E));var b=(65535&R)+E;S+f>=x&&(x=(M=this.ensureBuffer(S+f)).length);for(var C=0;C<f;++C,++S)M[S]=M[S-b]}}}else{var w,A=this.bytes,v=this.bytesPos;void 0===(w=A[v++])&&s("Bad block header in flate stream");var G=w;void 0===(w=A[v++])&&s("Bad block header in flate stream"),G|=w<<8,void 0===(w=A[v++])&&s("Bad block header in flate stream");var P=w;void 0===(w=A[v++])&&s("Bad block header in flate stream"),(P|=w<<8)!=(65535&~G)&&s("Bad uncompressed block length in flate stream"),this.codeBuf=0,this.codeSize=0;var D=this.bufferLength,M=this.ensureBuffer(D+G),k=D+G;this.bufferLength=k;for(var F=D;F<k;++F){if(void 0===(w=A[v++])){this.eof=!0;break}M[F]=w}this.bytesPos=v}},i}(),PNG=function(){class e{static load(t,r,a){"function"==typeof r&&(a=r);const n=new XMLHttpRequest;return n.open("GET",t,!0),n.responseType="arraybuffer",n.onload=()=>{const t=new Uint8Array(n.response||n.mozResponseArrayBuffer),s=new e(t);return"function"==typeof(r&&r.getContext)&&s.render(r),"function"==typeof a?a(s):void 0},n.send(null)}constructor(e){let t;this.data=e,this.pos=8,this.palette=[],this.imgData=[],this.transparency={},this.animation=null,this.text={};let r=null;for(;;){var a;let e=this.readUInt32(),d="";for(t=0;t<4;t++)d+=String.fromCharCode(this.data[this.pos++]);switch(d){case"IHDR":this.width=this.readUInt32(),this.height=this.readUInt32(),this.bits=this.data[this.pos++],this.colorType=this.data[this.pos++],this.compressionMethod=this.data[this.pos++],this.filterMethod=this.data[this.pos++],this.interlaceMethod=this.data[this.pos++];break;case"acTL":this.animation={numFrames:this.readUInt32(),numPlays:this.readUInt32()||1/0,frames:[]};break;case"PLTE":this.palette=this.read(e);break;case"fcTL":r&&this.animation.frames.push(r),this.pos+=4,r={width:this.readUInt32(),height:this.readUInt32(),xOffset:this.readUInt32(),yOffset:this.readUInt32()};var n=this.readUInt16(),s=this.readUInt16()||100;r.delay=1e3*n/s,r.disposeOp=this.data[this.pos++],r.blendOp=this.data[this.pos++],r.data=[];break;case"IDAT":case"fdAT":for("fdAT"===d&&(this.pos+=4,e-=4),a=r&&r.data||this.imgData,t=0;t<e;t++)a.push(this.data[this.pos++]);break;case"tRNS":switch(this.transparency={},this.colorType){case 3:this.transparency.indexed=this.read(e);var i=255-this.transparency.indexed.length;if(i>0)for(t=0;t<i;t++)this.transparency.indexed.push(255);break;case 0:this.transparency.grayscale=this.read(e)[0];break;case 2:this.transparency.rgb=this.read(e)}break;case"tEXt":var o=this.read(e),l=o.indexOf(0),c=String.fromCharCode.apply(String,o.slice(0,l));this.text[c]=String.fromCharCode.apply(String,o.slice(l+1));break;case"IEND":switch(r&&this.animation.frames.push(r),this.colorType){case 0:case 3:case 4:this.colors=1;break;case 2:case 6:this.colors=3}this.hasAlphaChannel=[4,6].includes(this.colorType);var u=this.colors+(this.hasAlphaChannel?1:0);switch(this.pixelBitlength=this.bits*u,this.colors){case 1:this.colorSpace="DeviceGray";break;case 3:this.colorSpace="DeviceRGB"}return void(this.imgData=new Uint8Array(this.imgData));default:this.pos+=e}if(this.pos+=4,this.pos>this.data.length)throw new Error("Incomplete or corrupt PNG file")}}read(e){const t=new Array(e);for(let r=0;r<e;r++)t[r]=this.data[this.pos++];return t}readUInt32(){return this.data[this.pos++]<<24|this.data[this.pos++]<<16|this.data[this.pos++]<<8|this.data[this.pos++]}readUInt16(){return this.data[this.pos++]<<8|this.data[this.pos++]}decodePixels(e){if(null==e&&(e=this.imgData),0===e.length)return new Uint8Array(0);e=(e=new FlateStream(e)).getBytes();const{width:t,height:r}=this,a=this.pixelBitlength/8,n=new Uint8Array(t*r*a),{length:s}=e;let i=0;function o(o,l,c,u,d=!1){const p=Math.ceil((t-o)/c),g=Math.ceil((r-l)/u),m=a*p,h=d?n:new Uint8Array(m*g);let f=0,y=0;for(;f<g&&i<s;){var _,T,x,S,R;switch(e[i++]){case 0:for(x=0;x<m;x++)h[y++]=e[i++];break;case 1:for(x=0;x<m;x++)_=e[i++],S=x<a?0:h[y-a],h[y++]=(_+S)%256;break;case 2:for(x=0;x<m;x++)_=e[i++],T=(x-x%a)/a,R=f&&h[(f-1)*m+T*a+x%a],h[y++]=(R+_)%256;break;case 3:for(x=0;x<m;x++)_=e[i++],T=(x-x%a)/a,S=x<a?0:h[y-a],R=f&&h[(f-1)*m+T*a+x%a],h[y++]=(_+Math.floor((S+R)/2))%256;break;case 4:for(x=0;x<m;x++){var E,b;_=e[i++],T=(x-x%a)/a,S=x<a?0:h[y-a],0===f?R=b=0:(R=h[(f-1)*m+T*a+x%a],b=T&&h[(f-1)*m+(T-1)*a+x%a]);const t=S+R-b,r=Math.abs(t-S),n=Math.abs(t-R),s=Math.abs(t-b);E=r<=n&&r<=s?S:n<=s?R:b,h[y++]=(_+E)%256}break;default:throw new Error(`Invalid filter algorithm: ${e[i-1]}`)}if(!d){let e=((l+f*u)*t+o)*a,r=f*m;for(x=0;x<p;x++){for(let t=0;t<a;t++)n[e++]=h[r++];e+=(c-1)*a}}f++}}return 1===this.interlaceMethod?(o(0,0,8,8),o(4,0,8,8),o(0,4,4,8),o(2,0,4,4),o(0,2,2,4),o(1,0,2,2),o(0,1,1,2)):o(0,0,1,1,!0),n}decodePalette(){const{palette:e}=this,{length:t}=e,r=this.transparency.indexed||[],a=new Uint8Array((r.length||0)+t);let n=0,s=0;for(let o=0;o<t;o+=3){var i;a[n++]=e[o],a[n++]=e[o+1],a[n++]=e[o+2],a[n++]=null!=(i=r[s++])?i:255}return a}copyToImageData(e,t){let r,a,{colors:n}=this,s=null,i=this.hasAlphaChannel;this.palette.length&&(s=this._decodedPalette||(this._decodedPalette=this.decodePalette()),n=4,i=!0);const o=e.data||e,{length:l}=o,c=s||t;let u=r=0;if(1===n)for(;u<l;){a=s?4*t[u/4]:r;const e=c[a++];o[u++]=e,o[u++]=e,o[u++]=e,o[u++]=i?c[a++]:255,r=a}else for(;u<l;)a=s?4*t[u/4]:r,o[u++]=c[a++],o[u++]=c[a++],o[u++]=c[a++],o[u++]=i?c[a++]:255,r=a}decode(){const e=new Uint8Array(this.width*this.height*4);return this.copyToImageData(e,this.decodePixels()),e}renderFrame(e,t){const{frames:r}=this.animation,a=r[t],n=r[t-1];return 0===t&&e.clearRect(0,0,this.width,this.height),1===(n&&n.disposeOp)?e.clearRect(n.xOffset,n.yOffset,n.width,n.height):2===(n&&n.disposeOp)&&e.putImageData(n.imageData,n.xOffset,n.yOffset),0===a.blendOp&&e.clearRect(a.xOffset,a.yOffset,a.width,a.height),e.drawImage(a.image,a.xOffset,a.yOffset)}animate(e){let t=0;const{numFrames:r,frames:a,numPlays:n}=this.animation,s=()=>{const i=t++%r,o=a[i];this.renderFrame(e,i),r>1&&t/r<n&&(this.animation._timeout=setTimeout(s,o.delay))};s()}stopAnimation(){return clearTimeout(this.animation&&this.animation._timeout)}render(e){e._png&&e._png.stopAnimation(),e._png=this,e.width=this.width,e.height=this.height;const t=e.getContext("2d");if(this.animation)return this.decodeFrames(t),this.animate(t);{const e=t.createImageData(this.width,this.height);return this.copyToImageData(e,this.decodePixels()),t.putImageData(e,0,0)}}}return e}();function createSceneSpec(e){return{assetType:"scene",occupancyGridsSpec:createOccupancyGridsSpec(e),distanceGridsSpec:createDistanceGridsSpec(e),triplaneSpec:createTriplaneSpec(e),sparseGridSpec:createSparseGridSpec(e)}}function createOccupancyGridsSpec(e){let t=[8,16,32,64,128];return e.useBits&&(t=[8,32,128]),e.useDistanceGrid&&(t=[8]),{assetType:"occupancy_grids",gridSpecs:t.map((t=>createOccupancyGridSpec(e,"occupancy_grid",t))),blockSizes:t}}function createDistanceGridsSpec(e){if(!e.useDistanceGrid)return{assetType:"distance_grids",gridSpecs:[],blockSizes:[]};return{assetType:"distance_grids",gridSpecs:[createOccupancyGridSpec(e,"distance_grid",8)],blockSizes:[8]}}function createSparseGridSpec(e){e.export_array_format;let t=getFieldOrDefault(e,"export_store_rgb_and_density_separately",!1),r={assetType:"sparse_grid",blockIndicesSpec:createSparseGridBlockIndicesSpec(e),separateRgbAndDensity:t};return t?(r.rgbSpec=createSparseGridAssetSpec(e,"sparse_grid_rgb",3),r.densitySpec=createSparseGridAssetSpec(e,"sparse_grid_density",2),r.featuresSpec=createSparseGridAssetSpec(e,"sparse_grid_features",3)):(r.rgbAndDensitySpec=createSparseGridAssetSpec(e,"sparse_grid_rgb_and_density",4),r.featuresSpec=createSparseGridAssetSpec(e,"sparse_grid_features",4)),r}function createSparseGridBlockIndicesSpec(e){const t=e.export_array_format||"png";let r=e.sparse_grid_resolution/e.data_block_size;return{assetType:"sparse_grid_block_indices",filename:`sparse_grid_block_indices.${t}`,shape:[r,r,r],numChannels:3}}function createSparseGridAssetSpec(e,t,r){const a=e.export_array_format||"png";let n=e.num_slices,s=e.atlas_width,i=e.atlas_height,o=e.atlas_depth,l=Math.ceil(o/n),c=[];for(let e=0;e<n;++e){const o=digits(e,3);filename=`${t}_${o}.${a}`,c.push({assetType:`${t}_slice`,shape:[s,i,l],numChannels:r,sliceIndex:e,numSlices:n,filename:filename})}return{assetType:`${t}_slices`,shape:[s,i,o],numChannels:r,sliceSpecs:c,numSlices:n,mergeSlices:getMergeSlices(e)}}function createOccupancyGridSpec(e,t,r){const a=e.export_array_format||"png",n=e.triplane_resolution,s=e.triplane_voxel_size,i=Math.ceil(n/r),o=s*r;const l=getFieldOrDefault(e,"export_slice_occupancy_and_distance_grids",!0)&&i>256;let c=getFieldOrDefault(e,"export_pad_occupancy_and_distance_grids",!0)?4:1,u=[];if(e.legacyGrids||!l){let n=`${t}_${r}.${a}`;e.legacyGrids||(n=`${t}_${r}_000.${a}`),u.push({assetType:`${t}_slice`,shape:[i,i,i],numChannels:c,sliceIndex:0,numSlices:1,filename:n})}else{const e=Math.ceil(i/8);for(let n=0;n<8;++n){let s=`${t}_${r}_${digits(n,3)}.${a}`;u.push({assetType:`${t}_slice`,shape:[i,i,e],numChannels:c,sliceIndex:n,numSlices:8,filename:s})}}return{assetType:`${t}_slices`,shape:[i,i,i],numChannels:c,voxelSize:o,blockSize:r,sliceSpecs:u,numSlices:8,mergeSlices:getMergeSlices(e)}}function createTriplaneSpec(e){const t=e.triplane_resolution;let r={assetType:"triplane",shape:[t,t,3],numSlices:3,voxelSize:e.triplane_voxel_size,separateRgbAndDensity:getFieldOrDefault(e,"export_store_rgb_and_density_separately",!1),featuresSpec:createTriplaneSlicesSpec(e,"triplane_features",4)};return r.separateRgbAndDensity?(r.rgbSpec=createTriplaneSlicesSpec(e,"triplane_rgb",3),r.densitySpec=createTriplaneSlicesSpec(e,"triplane_density",1)):r.rgbAndDensitySpec=createTriplaneSlicesSpec(e,"triplane_rgb_and_density",4),r}function createTriplaneSlicesSpec(e,t,r){const a=e.triplane_resolution;return{assetType:`${t}_slices`,shape:[a,a,3],numChannels:r,numSlices:3,mergeSlices:getMergeSlices(e),sliceSpecs:range(3).map((a=>createPlaneSliceSpec(e,t,r,a)))}}function createPlaneSliceSpec(e,t,r,a){const n=e.export_array_format||"png",s=e.triplane_resolution;let i=t.replace(/^triplane_/,"plane_");return{assetType:`${t}_slice`,shape:[s,s,1],numChannels:r,sliceIndex:a,numSlices:3,filename:`${i}_${a}.${n}`}}function getMergeSlices(e){const t=getFieldOrDefault(e,"export_store_rgb_and_density_separately",!1),r=getFieldOrDefault(e,"merge_slices",!t);if(!t&&!r)throw new Error('Slices must be merged when using "rgb_and_density" images. Please re-export with export_store_rgb_and_density_separately=true and try again.');return r&&t}const baseGoogleApiUrl="https://firebasestorage.googleapis.com/v0/b/test3-2d896.appspot.com/o";let gcsToken=null;function fetchGcsToken(){return gcsToken||(gcsToken=fetch("http://localhost:3001/get-gcs-token").then((e=>{if(!e.ok)throw new Error(`Erreur lors de la récupération du jeton GCS: ${e.status}`);return e.json()})).then((e=>(gcsToken=e.token,setTimeout((()=>{gcsToken=null}),84e4),gcsToken))).catch((e=>{throw console.error("Erreur lors de la récupération du jeton GCS:",e),gcsToken=null,e})),gcsTokenPromise)}function fetchScene(e,t){return{...e,occupancyGridsAsset:fetchAsset(e.occupancyGridsSpec,t),distanceGridsAsset:fetchAsset(e.distanceGridsSpec,t),triplaneAsset:fetchAsset(e.triplaneSpec,t),sparseGridAsset:fetchAsset(e.sparseGridSpec,t)}}function fetchOccupancyGrids(e,t){let r=e.gridSpecs.map((e=>fetchAsset(e,t)));return{...e,gridAssets:r}}function fetchSlices(e,t){let r=e.sliceSpecs.map((e=>fetchAsset(e,t)));return{...e,sliceAssets:r}}function fetchTriplane(e,t){let r={...e,featuresAsset:fetchAsset(e.featuresSpec,t)};return e.separateRgbAndDensity?(r.rgbAsset=fetchAsset(e.rgbSpec,t),r.densityAsset=fetchAsset(e.densitySpec,t)):r.rgbAndDensityAsset=fetchAsset(e.rgbAndDensitySpec,t),r}function fetchArray(e,t){const r=t.dirUrl;if("string"!=typeof r)throw console.error("dirUrl is not a valid string:",r),new Error("dirUrl must be a valid string");if(!e.filename)throw console.error("Spec missing filename:",e),new Error("Spec must contain a valid filename");const a=cleanPath(r),n=e.filename.endsWith(".gz")?e.filename.slice(0,-3):e.filename,s=encodeURIComponent(a),i=`${baseGoogleApiUrl}/users%2Fvisite_3D%2F${s}%2F${n}?alt=media&token=${gcsToken}`;console.log("Fetching from URL:",i);const o=loadAsset(i).then(validateSize(e)).then(onImageLoaded);return{...e,asset:o}}function validateSize(e){return t=>{const r=product(e.shape)*e.numChannels;return console.assert(t.length===r,`Size mismatch for ${e.filename}`,e,t),t}}function cleanPath(e){const t=e.split("/"),r=[];for(let e=0;e<t.length;e++)".."===t[e]?r.length&&r.pop():"."!==t[e]&&""!==t[e]&&r.push(t[e]);return r.join("/")}function fetchSparseGrid(e,t){let r={...e,blockIndicesAsset:fetchAsset(e.blockIndicesSpec,t),featuresAsset:fetchAsset(e.featuresSpec,t)};return e.separateRgbAndDensity?(r.rgbAsset=fetchAsset(e.rgbSpec,t),r.densityAsset=fetchAsset(e.densitySpec,t)):r.rgbAndDensityAsset=fetchAsset(e.rgbAndDensitySpec,t),r}function notImplementedError(e,t){console.error(`${e.assetType} is not yet implemented`,e)}const gFetchRegistry={scene:fetchScene,triplane:fetchTriplane,triplane_rgb_and_density_slices:fetchSlices,triplane_rgb_and_density_slice:fetchArray,triplane_rgb_slices:fetchSlices,triplane_rgb_slice:fetchArray,triplane_density_slices:fetchSlices,triplane_density_slice:fetchArray,triplane_features_slices:fetchSlices,triplane_features_slice:fetchArray,distance_grids:fetchOccupancyGrids,distance_grid_slices:fetchSlices,distance_grid_slice:fetchArray,occupancy_grids:fetchOccupancyGrids,occupancy_grid_slices:fetchSlices,occupancy_grid_slice:fetchArray,sparse_grid:fetchSparseGrid,sparse_grid_block_indices:fetchArray,sparse_grid_rgb_and_density_slices:fetchSlices,sparse_grid_rgb_and_density_slice:fetchArray,sparse_grid_rgb_slices:fetchSlices,sparse_grid_rgb_slice:fetchArray,sparse_grid_density_slices:fetchSlices,sparse_grid_density_slice:fetchArray,sparse_grid_features_slices:fetchSlices,sparse_grid_features_slice:fetchArray};function fetchAsset(e,t){let r=gFetchRegistry[e.assetType];return null==r&&console.error(`Failed to find fetchFn for assetType ${e.assetType}`,e),r(e,t)}function createEmptyVolumeTexture(e,t,r,a,n){let s=new THREE.DataTexture3D(null,e,t,r);return s.internalFormat=getInternalFormat(a),s.format=a,s.generateMipmaps=!1,s.magFilter=s.minFilter=n,s.wrapS=s.wrapT=s.wrapR=THREE.ClampToEdgeWrapping,s.type=THREE.UnsignedByteType,s.unpackAlignment=1,gRenderer.initTexture(s),s}function createEmptyTriplaneTextureArray(e,t,r,a){let n=new THREE.DataTexture2DArray(null,e,t,r);return n.internalFormat=getInternalFormat(a),n.format=a,n.generateMipmaps=!1,n.magFilter=n.minFilter=THREE.LinearFilter,n.wrapS=n.wrapT=n.wrapR=THREE.ClampToEdgeWrapping,n.type=THREE.UnsignedByteType,n.unpackAlignment=1,gRenderer.initTexture(n),n}function getInternalFormat(e){if(e==THREE.RedFormat)return"R8";if(e==THREE.LuminanceAlphaFormat)return"LUMINANCE_ALPHA";if(e==THREE.RGBFormat)return"RGB";if(e==THREE.RGBAFormat)return"RGBA";throw new Error(`Unrecognized THREE.js format: ${e}`)}function createEmptySceneTexture(e){return{textureType:"scene",occupancyGridsTexture:createEmptyTexture(e.occupancyGridsSpec),distanceGridsTexture:createEmptyTexture(e.distanceGridsSpec),triplaneTexture:createEmptyTexture(e.triplaneSpec),sparseGridTexture:createEmptyTexture(e.sparseGridSpec)}}function createEmptyOccupancyGridsTexture(e){return{textureType:e.assetType.replace(/_slices$/,""),gridTextures:e.gridSpecs.map(createEmptyTexture)}}function createEmptyOccupancyGridTexture(e){return{textureType:e.assetType.replace(/_slices$/,""),texture:createEmptyVolumeTexture(...e.shape,THREE.RedFormat,THREE.NearestFilter)}}function createEmptyTriplaneTexture(e){let t={textureType:"triplane",featuresTexture:createEmptyTexture(e.featuresSpec)};if(e.separateRgbAndDensity)t.rgbTexture=createEmptyTexture(e.rgbSpec),t.densityTexture=createEmptyTexture(e.densitySpec);else{let r=e.rgbAndDensitySpec.shape;t.rgbTexture=createEmptyTexture({assetType:"triplane_rgb_slices",shape:r}),t.densityTexture=createEmptyTexture({assetType:"triplane_density_slices",shape:r})}return t}function createEmptyTriplaneSlicesTexture(e){let t=e.assetType.replace(/_slices$/,""),r={triplane_density:THREE.RedFormat,triplane_rgb:THREE.RGBFormat,triplane_features:THREE.RGBAFormat}[t];return console.assert(null!=r,e),{textureType:t,texture:createEmptyTriplaneTextureArray(...e.shape,r)}}function createEmptySparseGridTexture(e){let t=(e,t)=>createEmptyVolumeTexture(...e.shape,t,THREE.LinearFilter),r=e.separateRgbAndDensity?e.rgbSpec:e.rgbAndDensitySpec,a=e.separateRgbAndDensity?e.densitySpec:e.rgbAndDensitySpec,n=t(r,THREE.RGBFormat),s=t(a,THREE.LuminanceAlphaFormat),i=t(e.featuresSpec,THREE.RGBFormat);return{textureType:"sparse_grid",blockIndicesTexture:{textureType:"sparse_grid_block_indices",texture:createEmptyVolumeTexture(...e.blockIndicesSpec.shape,THREE.RGBFormat,THREE.NearestFilter)},rgbTexture:{textureType:"sparse_grid_rgb",texture:n},densityTexture:{textureType:"sparse_grid_density",texture:s},featuresTexture:{textureType:"sparse_grid_features",texture:i}}}const gCreateEmptyTextureRegistry={scene:createEmptySceneTexture,triplane:createEmptyTriplaneTexture,triplane_rgb_slices:createEmptyTriplaneSlicesTexture,triplane_density_slices:createEmptyTriplaneSlicesTexture,triplane_features_slices:createEmptyTriplaneSlicesTexture,distance_grids:createEmptyOccupancyGridsTexture,distance_grid_slices:createEmptyOccupancyGridTexture,occupancy_grids:createEmptyOccupancyGridsTexture,occupancy_grid_slices:createEmptyOccupancyGridTexture,sparse_grid:createEmptySparseGridTexture};function createEmptyTexture(e){let t=gCreateEmptyTextureRegistry[e.assetType];return null==t&&console.error(`Failed to find loadFn for assetType ${e.assetType}`,e),t(e)}function prepareScenePayload(e){return{textureType:"scene",occupancyGridsPayload:prepareTexturePayload(e.occupancyGridsAsset),distanceGridsPayload:prepareTexturePayload(e.distanceGridsAsset),triplanePayload:prepareTexturePayload(e.triplaneAsset),sparseGridPayload:prepareTexturePayload(e.sparseGridAsset)}}function prepareOccupancyGridsPayload(e){return{textureType:e.assetType,gridPayloads:e.gridAssets.map(prepareTexturePayload)}}function prepareOccupancyGridPayload(e){return e.mergeSlices?prepareOccupancyGridMergedPayload(e):prepareOccupancyGridSlicesPayload(e)}function prepareOccupancyGridMergedPayload(e){return console.assert(e.assetType.endsWith("_slices"),e),{textureType:e.assetType.replace(/_slices$/,""),shape:e.shape,numChannels:e.numChannels,payload:mergeSlices(e,{1:GridTextureSource.RED_FROM_RED,4:GridTextureSource.ALPHA_FROM_RGBA}[e.numChannels],GridTextureDestination.RED_IN_RED)}}function prepareOccupancyGridSlicesPayload(e){return console.assert(e.assetType.endsWith("_slices"),e),{textureType:e.assetType.replace(/_slices$/,""),shape:e.shape,numChannels:e.numChannels,slicePayloads:e.sliceAssets.map(prepareTexturePayload)}}function prepareOccupancyGridSlicePayload(e){console.assert(e.assetType.endsWith("_slice"),e);let t=null;if(1==e.numChannels)t=e.asset;else{if(4!=e.numChannels)throw new Error("Unrecognized number of input channels",e);t=mergeSlices({shape:e.shape,numSlices:1,sliceAssets:[{...e,sliceIndex:0,numSlices:1}]},GridTextureSource.ALPHA_FROM_RGBA,GridTextureDestination.RED_IN_RED)}return{textureType:e.assetType,shape:e.shape,numChannels:e.numChannels,sliceIndex:e.sliceIndex,numSlices:e.numSlices,payload:t}}function prepareTriplanePayload(e){let t={textureType:"triplane",featuresPayload:preparePlanePayload(e.featuresAsset,"triplane_features",GridTextureSource.RGBA_FROM_RGBA,GridTextureDestination.RGBA_IN_RGBA)};return e.separateRgbAndDensity?(t.rgbPayload=preparePlanePayload(e.rgbAsset,"triplane_rgb",GridTextureSource.RGB_FROM_RGB,GridTextureDestination.RGB_IN_RGB),t.densityPayload=preparePlanePayload(e.densityAsset,"triplane_density",GridTextureSource.RED_FROM_RED,GridTextureDestination.RED_IN_RED)):(t.rgbPayload=preparePlanePayload(e.rgbAndDensityAsset,"triplane_rgb",GridTextureSource.RGB_FROM_RGBA,GridTextureDestination.RGB_IN_RGB),t.densityPayload=preparePlanePayload(e.rgbAndDensityAsset,"triplane_density",GridTextureSource.ALPHA_FROM_RGBA,GridTextureDestination.RED_IN_RED)),t}function preparePlanePayload(e,t,r,a){let n={textureType:t,shape:e.shape,numChannels:e.numChannels};return e.mergeSlices?n.payload=mergeSlices(e,r,a):n.slicePayloads=e.sliceAssets.map((e=>preparePlaneSlicePayload(e,r,a))),n}function preparePlaneSlicePayload(e,t,r){let a=null;return a=t.format==r.format&&t.channels==r.channels?e.asset:mergeSlices({shape:e.shape,numSlices:1,sliceAssets:[{...e,sliceIndex:0,numSlices:1}]},t,r),{textureType:e.assetType,shape:e.shape,sliceIndex:e.sliceIndex,numSlices:e.numSlices,numChannels:e.numChannels,payload:a}}function prepareArrayPayload(e){return{textureType:e.assetType,payload:e.asset,shape:e.shape,numChannels:e.numChannels}}function prepareSparseGridPayload(e){let t={textureType:"sparse_grid",blockIndicesPayload:prepareTexturePayload(e.blockIndicesAsset),featuresPayload:prepareTexturePayload(e.featuresAsset)};return e.separateRgbAndDensity?(t.rgbPayload=prepareTexturePayload(e.rgbAsset),t.densityPayload=prepareTexturePayload(e.densityAsset)):(t.rgbPayload=prepareTexturePayload(e.rgbAndDensityAsset),t.densityPayload=prepareSparseGridDensityPayload(e)),t}function prepareSparseGridGenericPayload(e){return e.mergeSlices?prepareSparseGridGenericMergedPayload(e):prepareSparseGridGenericSlicesPayload(e)}function prepareSparseGridGenericMergedPayload(e){let t=e.assetType.replace(/_slices$/,"");t.includes("rgb_and_density")&&(t=t.replace(/rgb_and_density$/,"rgb"));let r={2:GridTextureSource.LA_FROM_LUMINANCE_ALPHA,3:GridTextureSource.RGB_FROM_RGB,4:GridTextureSource.RGB_FROM_RGBA},a={2:GridTextureDestination.LA_IN_LUMINANCE_ALPHA,3:GridTextureDestination.RGB_IN_RGB,4:GridTextureDestination.RGB_IN_RGB},n=mergeSlices(e,r[e.numChannels],a[e.numChannels]);return{textureType:t,shape:e.shape,numChannels:e.numChannels,payload:n}}function prepareSparseGridGenericSlicesPayload(e){let t=e.assetType.replace(/_slices$/,"");return t.includes("rgb_and_density")&&(t=t.replace(/rgb_and_density$/,"rgb")),{textureType:t,shape:e.shape,numChannels:e.numChannels,numSlices:e.numSlices,slicePayloads:e.sliceAssets.map(prepareTexturePayload)}}function prepareSparseGridGenericSlicePayload(e){let t=e.assetType,r=null;if("sparse_grid_rgb_slice"==t&&3==e.numChannels||"sparse_grid_density_slice"==t&&2==e.numChannels||"sparse_grid_features_slice"==t&&3==e.numChannels)r=e.asset;else{let t={2:GridTextureSource.LA_FROM_LUMINANCE_ALPHA,3:GridTextureSource.RGB_FROM_RGB,4:GridTextureSource.RGB_FROM_RGBA},a={2:GridTextureDestination.LA_IN_LUMINANCE_ALPHA,3:GridTextureDestination.RGB_IN_RGB,4:GridTextureDestination.RGB_IN_RGB};r=mergeSlices({shape:e.shape,numSlices:1,sliceAssets:[{...e,sliceIndex:0,numSlices:1}]},t[e.numChannels],a[e.numChannels])}let a=t;return a.includes("rgb_and_density")&&(a=a.replace(/_rgb_and_density$/,"rgb")),{textureType:a,shape:e.shape,numChannels:e.numChannels,sliceIndex:e.sliceIndex,numSlices:e.numSlices,payload:r}}function prepareSparseGridDensityPayload(e){return{textureType:"sparse_grid_density",shape:e.rgbAndDensityAsset.shape,numChannels:2,payload:mergeSparseGridDensity(e)}}const gPrepareTexturePayloadRegistry={scene:prepareScenePayload,triplane:prepareTriplanePayload,distance_grids:prepareOccupancyGridsPayload,distance_grid_slices:prepareOccupancyGridPayload,distance_grid_slice:prepareOccupancyGridSlicePayload,occupancy_grids:prepareOccupancyGridsPayload,occupancy_grid_slices:prepareOccupancyGridPayload,occupancy_grid_slice:prepareOccupancyGridSlicePayload,sparse_grid:prepareSparseGridPayload,sparse_grid_block_indices:prepareArrayPayload,sparse_grid_rgb_and_density_slices:prepareSparseGridGenericPayload,sparse_grid_rgb_and_density_slice:prepareSparseGridGenericSlicePayload,sparse_grid_rgb_slices:prepareSparseGridGenericPayload,sparse_grid_rgb_slice:prepareSparseGridGenericSlicePayload,sparse_grid_density_slices:prepareSparseGridGenericPayload,sparse_grid_density_slice:prepareSparseGridGenericSlicePayload,sparse_grid_features_slices:prepareSparseGridGenericPayload,sparse_grid_features_slice:prepareSparseGridGenericSlicePayload};function prepareTexturePayload(e){let t=gPrepareTexturePayloadRegistry[e.assetType];return null==t&&console.error(`Failed to find loadFn for assetType ${e.assetType}`,e),t(e)}function populateScene(e,t){let r=[populateTexture(e.occupancyGridsTexture,t.occupancyGridsPayload),populateTexture(e.distanceGridsTexture,t.distanceGridsPayload),populateTexture(e.triplaneTexture,t.triplanePayload),populateTexture(e.sparseGridTexture,t.sparseGridPayload)];return Promise.all(r)}function populateOccupancyGridsTexture(e,t){console.assert(e.gridTextures.length==t.gridPayloads.length,e,t);let r=range(e.gridTextures.length).map((r=>populateTexture(e.gridTextures[r],t.gridPayloads[r])));return Promise.all(r)}function populateSparseGridTexture(e,t){let r=[populateTexture(e.blockIndicesTexture,t.blockIndicesPayload),populateTexture(e.rgbTexture,t.rgbPayload),populateTexture(e.densityTexture,t.densityPayload),populateTexture(e.featuresTexture,t.featuresPayload)];return Promise.all(r)}function populateTriplaneTexture(e,t){return Promise.all([populateTexture(e.rgbTexture,t.rgbPayload),populateTexture(e.densityTexture,t.densityPayload),populateTexture(e.featuresTexture,t.featuresPayload)])}async function populateArrayTexture(e,t){if(null==t.payload)throw new Error("Unclear how to ingest payload",e,t);e.texture.image.data=await t.payload,e.texture.needsUpdate=!0}function populateArrayTextureWithWebGL(e,t){if(null!=t.payload)return populateArrayTextureMergedWithWebGL(e,t);if(null!=t.slicePayloads){let r=t.slicePayloads.map((t=>populateArrayTextureSliceWithWebGL(e,t)));return Promise.all(r)}throw new Error("Unclear how to ingest payload",e,t)}async function populateArrayTextureSliceWithWebGL(e,t){let r=gRenderer.getContext();const a=t.shape[0],n=t.shape[1],s=t.shape[2],i=t.sliceIndex;let o=e.texture.format,{glFormat:l,glInternalFormat:c,numChannels:u}=threeFormatToOpenGLFormat(r,o),d=await t.payload;let p,g,m=gRenderer.properties.get(e.texture).__webglTexture;console.assert(null!=m,e),e.texture instanceof THREE.DataTexture3D?(p=r.TEXTURE_BINDING_3D,g=r.TEXTURE_3D):e.texture instanceof THREE.DataTexture2DArray&&(p=r.TEXTURE_BINDING_2D_ARRAY,g=r.TEXTURE_2D_ARRAY);let h=r.getParameter(p);r.bindTexture(g,m);performance.mark(`${e.textureType}-start`);r.texSubImage3D(g,0,0,0,i*s,a,n,s,l,r.UNSIGNED_BYTE,d,0);performance.mark(`${e.textureType}-end`);performance.measure(`${e.textureType}-duration`,`${e.textureType}-start`,`${e.textureType}-end`),r.bindTexture(g,h)}async function populateArrayTextureMergedWithWebGL(e,t){return populateArrayTextureSliceWithWebGL(e,{...t,sliceIndex:0,numSlices:1})}function threeFormatToOpenGLFormat(e,t){if(t==THREE.RGBAFormat)return{numChannels:4,glFormat:e.RGBA,glInternalFormat:e.RGBA};if(t==THREE.RGBFormat)return{numChannels:3,glFormat:e.RGB,glInternalFormat:e.RGB};if(t==THREE.LuminanceAlphaFormat)return{numChannels:2,glFormat:e.LUMINANCE_ALPHA,glInternalFormat:e.LUMINANCE_ALPHA};if(t==THREE.RedFormat)return{numChannels:1,glFormat:e.RED,glInternalFormat:e.R8};throw new Error(`Unrecognized three format: ${t}`)}const gPopulateTextureRegistry={scene:populateScene,triplane:populateTriplaneTexture,triplane_rgb:populateArrayTextureWithWebGL,triplane_density:populateArrayTextureWithWebGL,triplane_features:populateArrayTextureWithWebGL,distance_grids:populateOccupancyGridsTexture,distance_grid:populateArrayTextureWithWebGL,occupancy_grids:populateOccupancyGridsTexture,occupancy_grid:populateArrayTextureWithWebGL,sparse_grid:populateSparseGridTexture,sparse_grid_block_indices:populateArrayTextureWithWebGL,sparse_grid_rgb:populateArrayTextureWithWebGL,sparse_grid_density:populateArrayTextureWithWebGL,sparse_grid_features:populateArrayTextureWithWebGL};function populateTexture(e,t){let r=gPopulateTextureRegistry[e.textureType];return null==r&&console.error(`Failed to find loadFn for assetType ${e.textureType}`,e),r(e,t)}const NEEDS_NEW_SUBMODEL=-1,LOADING=0,READY=1;let gSubmodelSceneContents={},gSubmodelCacheSize=10,gRayMarchTextureBuffers=[{si:0,state:-1,texture:null},{si:0,state:-1,texture:null}],gActiveRayMarchTextureBuffer=0,gRayMarchScene=null;function getRayMarchScene(){if(null==gRayMarchScene)throw new Error("gRayMarchScene has not been initialized yet!");return gRayMarchScene}function getActiveSubmodelIndex(){return gRayMarchTextureBuffers[gActiveRayMarchTextureBuffer].si}function getActiveSubmodelContent(){return getSubmodelContent(getActiveSubmodelIndex())}function getSubmodelScale(e){return getSubmodelContent(e).params.submodel_scale}function getSubmodelScaleFactor(e){let t=getSubmodelContent(e);return getSubmodelScale(e)/Math.cbrt(t.params.num_submodels)}function getSubmodelContent(e){return gSubmodelSceneContents[e]}function registerSubmodelContent(e,t){gSubmodelSceneContents[e]=t}function getDeferredMlp(){return console.assert(null!=gDeferredMlp),gDeferredMlp}function registerDeferredMlp(e){validateDeferredMlp(e),gDeferredMlp=e}function getCurrentTextureUsageInBytes(){let e=0;for(rmtb of gRayMarchTextureBuffers)e+=getTextureSizeInBytes(rmtb.texture);return e}function setCurrentRayMarchScene(e){let t=gActiveRayMarchTextureBuffer,r=gRayMarchTextureBuffers[t],a=(t+1)%2,n=gRayMarchTextureBuffers[a];if(null==getSubmodelContent(e))return Promise.resolve();if(getSubmodelContent(e).lastTouched=Date.now(),e==r.si&&r.state>=0)return Promise.resolve();if(e==n.si&&1==n.state){return console.log(`Switching to buffer ${a} for submodel #${e}`),setTextureUniforms(getSubmodelContent(e).params,n.texture),gActiveRayMarchTextureBuffer=a,Promise.resolve()}return n.state>=0&&n.state<1?Promise.resolve():(console.log(`Preparing texture buffer #${a} for submodel #${e}`),n.si=e,n.state=0,Promise.resolve().then((()=>{reinitializeSparseGridTextures(n);let e=getSubmodelContent(n.si);if(null==e.payload){console.log(`Fetching assets for submodel #${n.si}`);let t=prepareTexturePayload(fetchAsset(e.spec,e.router));e.payload=t}return console.log(`Populating textures for submodel #${n.si} into buffer #${a}`),populateTexture(n.texture,e.payload)})).then((()=>{n.state=1,console.log(`Submodel #${n.si} is ready for rendering`),hideLoading()})))}function garbageCollectSubmodelPayloads(){let e=[];for(let t of Object.keys(gSubmodelSceneContents)){let r=getSubmodelContent(t);null!=r.payload&&e.push({lastTouched:r.lastTouched||0,si:t})}e.sort(((e,t)=>e.lastTouched-t.lastTouched));for(let t=0;t<e.length-gSubmodelCacheSize;++t){let r=e[t].si;console.log(`Deleting payload for submodel #${r}`),getSubmodelContent(r).payload=null}}function initializeSceneContent(e,t){return{spec:createSceneSpec(e),params:e,router:t,payload:null}}function reinitializeSparseGridTextures(e){let t=e.texture.sparseGridTexture;t.blockIndicesTexture.texture.dispose(),t.rgbTexture.texture.dispose(),t.densityTexture.texture.dispose(),t.featuresTexture.texture.dispose();let r=getSubmodelContent(e.si).spec.sparseGridSpec;e.texture.sparseGridTexture=createEmptyTexture(r)}async function initializePingPongBuffers(e){let t=getSubmodelContent(e);gRayMarchScene=await initializeRayMarchScene(e,t);for(let e of gRayMarchTextureBuffers)e.texture=createEmptyTexture(t.spec);setTextureUniforms(t.params,gRayMarchTextureBuffers[0].texture),gActiveRayMarchTextureBuffer=0}async function initializeDeferredMlp(e){let t=getSubmodelContent(e),r=t.params;if(r.export_store_deferred_mlp_separately){return loadJSONFile(t.router.translate("deferred_mlp.json")).then(registerDeferredMlp)}return registerDeferredMlp(r.deferred_mlp)}function setTextureUniforms(e,t){let r=getRayMarchScene().children[0].material.uniforms,a=t.occupancyGridsTexture.gridTextures,n=a.length;for(let e=0;e<n;++e){let t=a[e];r["occupancyGrid_L"+(n-e-1)].value=t.texture}if(e.useDistanceGrid){let e=t.distanceGridsTexture.gridTextures[0].texture;r.distanceGrid.value=e}let s=t.triplaneTexture;r.planeDensity.value=s.densityTexture.texture,r.planeRgb.value=s.rgbTexture.texture,r.planeFeatures.value=s.featuresTexture.texture;let i=t.sparseGridTexture;r.sparseGridBlockIndices.value=i.blockIndicesTexture.texture,r.sparseGridDensity.value=i.densityTexture.texture,r.sparseGridRgb.value=i.rgbTexture.texture,r.sparseGridFeatures.value=i.featuresTexture.texture,r.atlasSize.value=new THREE.Vector3(e.atlas_width,e.atlas_height,e.atlas_depth)}function getTextureSizeInBytes(e){let t=0,r=e=>{if(null==e)return 0;let t=e.texture.image;return t.height*t.width*t.depth},a=e.occupancyGridsTexture.gridTextures,n=a.length;for(let e=0;e<n;++e){t+=1*r(a[e])}if(e.distanceGridsTexture.gridTextures.length>0){t+=1*r(e.distanceGridsTexture.gridTextures[0])}let s=e.triplaneTexture;t+=3*r(s.rgbTexture),t+=1*r(s.densityTexture),t+=4*r(s.featuresTexture);let i=e.sparseGridTexture;return t+=1*r(i.blockIndicesTexture),t+=3*r(i.rgbTexture),t+=1*r(i.densityTexture),t+=4*r(i.featuresTexture),t}async function initializeRayMarchScene(e,t){let r=t.params,a=t.spec,n=kRayMarchFragmentShaderHeader;n+=await loadTextFile("viewdependency.glsl"),n+=await loadTextFile("fragment.glsl"),n=rewriteViewDependenceDefinitions(r,n);let s=new THREE.Matrix3;s.set(-1,0,0,0,0,1,0,1,0);let i=new THREE.Vector3(-2,-2,-2);n="#define kMinPosition vec3("+Number(i.x).toFixed(10)+", "+Number(i.y).toFixed(10)+", "+Number(i.z).toFixed(10)+")\n"+n,n="#define kSubmodelScale "+Number(getSubmodelScale(e)).toFixed(10)+"\n"+n,n="#define kStepMult "+gStepMult+"\n"+n,n="#define kRangeFeaturesMin "+Number(r.range_features[0]).toFixed(10)+"\n"+n,n="#define kRangeFeaturesMax "+Number(r.range_features[1]).toFixed(10)+"\n"+n,n="#define kRangeDensityMin "+Number(r.range_density[0]).toFixed(10)+"\n"+n,n="#define kRangeDensityMax "+Number(r.range_density[1]).toFixed(10)+"\n"+n;let o={bias_0:{value:null},bias_1:{value:null},bias_2:{value:null},weightsZero:{value:null},weightsOne:{value:null},weightsTwo:{value:null},displayMode:{value:gDisplayMode-0},minPosition:{value:i},world_T_cam:{value:new THREE.Matrix4},cam_T_clip:{value:new THREE.Matrix4},worldspaceROpengl:{value:s}};occupancyUniforms={};let l=a.occupancyGridsSpec.gridSpecs,c=l.length;for(let e=0;e<c;++e){let t=l[e],r=c-e-1;n="#define kVoxelSizeOccupancy_L"+r+" "+Number(t.voxelSize).toFixed(10)+"\n"+n,n="#define kGridSizeOccupancy_L"+r+" vec3("+Number(t.shape[0]).toFixed(10)+", "+Number(t.shape[1]).toFixed(10)+", "+Number(t.shape[2]).toFixed(10)+")\n"+n,occupancyUniforms["occupancyGrid_L"+r]={value:null}}if(o=extend(o,occupancyUniforms),r.useDistanceGrid){let e=a.distanceGridsSpec.gridSpecs[0];n="#define USE_DISTANCE_GRID\n"+n,n="#define kVoxelSizeDistance "+Number(e.voxelSize).toFixed(10)+"\n"+n,n="#define kGridSizeDistance vec3("+Number(e.shape[0]).toFixed(10)+", "+Number(e.shape[1]).toFixed(10)+", "+Number(e.shape[2]).toFixed(10)+")\n"+n,distanceUniforms={distanceGrid:{value:null}},o=extend(o,distanceUniforms)}let u=new THREE.Color(.5,.5,.5);r.backgroundColor&&(u=new THREE.Color(r.backgroundColor)),n="#define kBackgroundColor vec3("+Number(u.r).toFixed(10)+", "+Number(u.g).toFixed(10)+", "+Number(u.b).toFixed(10)+")\n"+n,(gExposure||r.default_exposure)&&(r.default_exposure&&(gExposure=parseFloat(r.default_exposure)),n="#define USE_EXPOSURE\n"+n,exposureUniforms={exposure:{value:gExposure}},o=extend(o,exposureUniforms));n="#define ACTIVATION_FN "+(r.activation?r.activation:"elu")+"\n"+n,null!==r.feature_gating&&void 0!==r.feature_gating&&!0!==r.feature_gating||(n="#define USE_FEATURE_GATING\n"+n),"vfr"===r.deferred_rendering_mode&&(n="#define USE_VFR\n"+n),"coarse_sum"===r.merge_features_combine_op&&(n="#define USE_FEATURE_CONCAT\n"+n),r.useBits&&(n="#define USE_BITS\n"+n),r.useLargerStepsWhenOccluded&&(n="#define LARGER_STEPS_WHEN_OCCLUDED\n"+n,n="#define kVisibilityDelay "+Number(r.step_size_visibility_delay).toFixed(10)+"\n"+n);let d=new THREE.Vector2(...a.triplaneSpec.shape);n="#define kTriplaneVoxelSize "+Number(r.triplane_voxel_size).toFixed(10)+"\n"+n,n="#define kTriplaneGridSize vec2("+Number(d.x).toFixed(10)+", "+Number(d.y).toFixed(10)+")\n"+n;o=extend(o,{planeDensity:{value:null},planeRgb:{value:null},planeFeatures:{value:null}}),n="#define kDataBlockSize "+Number(r.data_block_size).toFixed(10)+"\n"+n,n="#define kSparseGridVoxelSize "+Number(r.sparse_grid_voxel_size).toFixed(10)+"\n"+n,n="#define kSparseGridGridSize vec3("+Number(r.sparse_grid_resolution).toFixed(10)+", "+Number(r.sparse_grid_resolution).toFixed(10)+", "+Number(r.sparse_grid_resolution).toFixed(10)+")\n"+n;o=extend(o,{sparseGridBlockIndices:{value:null},sparseGridDensity:{value:null},sparseGridRgb:{value:null},sparseGridFeatures:{value:null},atlasSize:{value:null}});let p=new THREE.ShaderMaterial({uniforms:o,vertexShader:kRayMarchVertexShader,fragmentShader:n,vertexColors:!0});p.side=THREE.DoubleSide,p.depthTest=!1,p.needsUpdate=!0;const g=new THREE.PlaneBufferGeometry(...gViewportDims);let m=new THREE.Mesh(g,p);m.position.z=-100,m.frustumCulled=!1;let h=new THREE.Scene;return h.add(m),h.autoUpdate=!1,h}function validateDeferredMlp(e){const t=e["ResampleDense_0/kernel"]?"ResampleDense":"Dense";for(let r=0;r<3;r++){const a=`${t}_${r}`;let n=e[`${a}/kernel`].shape,s=e[`${a}/bias`].shape;if("ResampleDense"===t){let e=n[1];console.assert(e===n[2]&&e===n[3]),console.assert(n[0]===s[0]&&n[1]===s[1]&&n[2]===s[2]&&n[3]===s[3])}}}class WorkerPool{constructor(e,t){let r=this;e=e||2,this.workers=[];for(let a=0;a<e;++a){let e=new Worker(t);e.onmessage=e=>{r.onmessage(e)},this.workers.push(e)}this.nextworker=0,this.callbacks={},this.i=0}submit(e,t){const r=this.i;this.callbacks[r]=t,this.i+=1;const a=this.nextworker,n=this.workers[a];this.nextworker=(a+1)%this.workers.length,n.postMessage({i:r,request:e})}onmessage(e){const t=e.data,r=t.i;(0,this.callbacks[r])(t.result),delete this.callbacks[r]}}let gStats=null,gUseSubmodel=!1,gSubmodelTransform=null,gDeferredMlp=null;const DisplayModeType={DISPLAY_NORMAL:0,DISPLAY_DIFFUSE:1,DISPLAY_FEATURES:2,DISPLAY_VIEW_DEPENDENT:3,DISPLAY_COARSE_GRID:4};let gDisplayMode=DisplayModeType.DISPLAY_NORMAL,gBenchmark=!1,gFrameMult=1,gLoadAssetsWorker=new WorkerPool(4,"loadpng.worker.js"),gCopySliceWorker=new WorkerPool(4,"copyslices.worker.js");const kRayMarchVertexShader="\nvarying vec3 vOrigin;\nvarying vec3 vDirection;\nuniform mat4 world_T_cam;\nuniform mat4 cam_T_clip;\n\nvoid main() {\n vec4 posClip = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n gl_Position = posClip;\n posClip /= posClip.w;\n\n vec4 originCam = vec4(0.0, 0.0, 0.0, 1.0);\n vec4 nearPointCam = cam_T_clip * vec4(posClip.x, posClip.y, -1.0, 1.0);\n nearPointCam /= -nearPointCam.z;\n\n vec4 originWorld = world_T_cam * originCam;\n vec4 nearPointWorld = world_T_cam * nearPointCam;\n vOrigin = originWorld.xyz / originWorld.w;\n vDirection = nearPointWorld.xyz / nearPointWorld.w - vOrigin;\n}\n",kRayMarchFragmentShaderHeader="\nprecision highp float;\n\nvarying vec3 vOrigin;\nvarying vec3 vDirection;\n\nuniform int displayMode;\n\nuniform mat3 worldspaceROpengl;\nuniform float nearPlane;\n\n#ifdef USE_DISTANCE_GRID\nuniform highp sampler3D distanceGrid;\nuniform highp sampler3D occupancyGrid_L0;\n#else\nuniform highp sampler3D occupancyGrid_L0;\nuniform highp sampler3D occupancyGrid_L1;\nuniform highp sampler3D occupancyGrid_L2;\n#ifndef USE_BITS\nuniform highp sampler3D occupancyGrid_L3;\nuniform highp sampler3D occupancyGrid_L4;\n#endif\n#endif\n\nuniform vec4 bias_0[NUM_CHANNELS_ONE/4];\nuniform vec4 bias_1[NUM_CHANNELS_TWO/4];\nuniform vec4 bias_2[NUM_CHANNELS_THREE/4];\n\nuniform highp sampler2D weightsZero;\nuniform highp sampler2D weightsOne;\nuniform highp sampler2D weightsTwo;\n\n#ifdef USE_EXPOSURE\nuniform float exposure;\n#endif\n\nuniform vec3 atlasSize;\n\nuniform highp sampler3D sparseGridBlockIndices;\nuniform highp sampler3D sparseGridDensity;\nuniform highp sampler3D sparseGridRgb;\nuniform highp sampler3D sparseGridFeatures;\n\n// need to use texture arrays, otherwise we exceed max texture unit limit\nuniform highp sampler2DArray planeDensity;\nuniform highp sampler2DArray planeRgb;\nuniform highp sampler2DArray planeFeatures;\n";let gRenderer=null,gSubmodelCount=1,gCamera=null,gViewportDims=[640,480],gNumTextures=0,gLoadedTextures=0,gSubmodelForceIndex=-1;function extend(e,t){for(let r in t)t.hasOwnProperty(r)&&(e[r]=t[r]);return e}function error(e){const t=document.getElementById("error");t.textContent=e,t.style.display="block"}function create(e,t){const r=document.createElement(e);return t&&(r.className=t),r}function digits(e,t){const r=""+e;return r.length>=t?r:("00000"+r).substr(-t)}function setupViewport(e,t){gViewportDims=[e,t]}function range(e){return[...Array(e).keys()]}function product(e){result=1;for(let t of e)result*=t;return result}function sum(e){result=1;for(let t of e)result+=t;return result}function setDims(e,t,r){e.style.width=t.toFixed(2)+"px",e.style.height=r.toFixed(2)+"px"}function hideLoading(){document.getElementById("Loading").style.display="none",document.getElementById("loading-container").style.display="none"}function showLoading(){document.getElementById("Loading").style.display="none",document.getElementById("loading-container").style.display="none"}function isLoading(){return"none"!==document.getElementById("Loading").style.display}function onImageFetch(e){return gNumTextures++,updateLoadingProgress(),e}function onImageLoaded(e){return gLoadedTextures++,updateLoadingProgress(),e}function updateLoadingProgress(){let e=document.getElementById("image-progress");const t=gNumTextures>0?gNumTextures:"?";e.innerHTML="Loading images: "+gLoadedTextures+"/"+t}function isRendererUnsupported(){let e=document.getElementById("Loading"),t=document.getElementsByTagName("canvas")[0].getContext("webgl2");return t?!t.getExtension("WEBGL_debug_renderer_info")&&(e.innerHTML="Error: Could not fetch renderer info. Is your machine equipped with a discrete GPU?",!0):(e.innerHTML="Error: WebGL2 context not found. Is your machine equipped with a discrete GPU?",!0)}function sleep(e){return new Promise((t=>setTimeout(t,e)))}function submodelAssetPath(e,t){let r="";if(gUseSubmodel){return r=`../sm_${String(e).padStart(3,"0")}`,null==t?r:`${r}/${t}`}return t}function positionToSubmodel(e,t){if(0==gUseSubmodel)return 0;if(gSubmodelForceIndex>=0)return gSubmodelForceIndex;let r=new THREE.Vector3(-e.x,e.z,e.y),a=2/t.submodel_voxel_size,n=r.addScalar(1).divideScalar(2);n=n.multiplyScalar(a);let s=n.floor().clampScalar(0,a-1);const i=(s.x*a+s.y)*a+s.z;return t.sm_to_params[i]}function submodelCenter(e,t){if(0==gUseSubmodel)return new THREE.Vector3(0,0,0);let r=t.submodel_voxel_size,a=2/r,n=t.params_to_sm[e],s=n%a,i=(n-s)/a%a,o=(n-s-i*a)/a/a;return o=a-1-o,[i,s]=[s,i],new THREE.Vector3((o+.5)*r-1,(i+.5)*r-1,(s+.5)*r-1)}function submodelTransform(e,t){const r=submodelCenter(e,t),a=t.submodel_scale;let n=new THREE.Matrix4;n.makeScale(a,a,a);let s=new THREE.Matrix4;return s.makeTranslation(-r.x,-r.y,-r.z),submodel_matrix=new THREE.Matrix4,submodel_matrix.multiplyMatrices(n,s),submodel_matrix}async function fetchAndRetryIfNecessary(e){const t=await e();return 429===t.status?(await sleep(500),fetchAndRetryIfNecessary(e)):t}function loadAsset(e){return new Promise((t=>{gLoadAssetsWorker.submit({url:e},t)}))}function mergeSlices(e,t,r){let a=e.sliceAssets.map((e=>e.asset));return Promise.all(a).then((a=>{let n=range(a.length).map((t=>({...e.sliceAssets[t],asset:a[t]}))),s={asset:{...e,sliceAssets:n},src:t,dst:r,fn:"mergeSlices"};return new Promise((e=>{gCopySliceWorker.submit(s,e)}))}))}function mergeSparseGridDensity(e){let t=e=>Promise.all(e.sliceAssets.map((e=>e.asset))),r=[t(e.rgbAndDensityAsset),t(e.featuresAsset)];return Promise.all(r).then((t=>{let r=t[0],a=t[1],n=(e,t)=>{let r=range(t.length).map((r=>({...e.sliceAssets[r],asset:t[r]})));return{...e,sliceAssets:r}},s=n(e.rgbAndDensityAsset,r),i=n(e.featuresAsset,a),o={asset:{assetType:e.assetType,rgbAndDensityAsset:s,featuresAsset:i},fn:"mergeSparseGridDensity"};return new Promise((e=>{gCopySliceWorker.submit(o,e)}))}))}function getFieldOrDefault(e,t,r){let a=e[t];return null==a?r:a}async function loadTextFile(e){try{const t=cleanPath(e),r=await fetch("http://localhost:3001/generate-signed-url",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({dirUrl:t})});if(!r.ok)throw new Error(`Erreur lors de la génération de l'URL signée: ${r.status}`);const{url:a}=await r.json();console.log("Tentative de chargement du fichier texte depuis:",a);const n=await fetch(a);if(!n.ok)throw new Error(`Erreur lors du téléchargement du fichier: ${n.status}`);const s=await n.text();return console.log("Contenu du fichier texte chargé depuis",a,":",s),s}catch(t){throw console.error(`Erreur lors de la récupération du fichier texte depuis ${e}:`,t),t}}async function loadJSONFile(e){try{const t=cleanPath(e),r=await fetch("http://localhost:3001/generate-signed-url",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({dirUrl:t})});if(console.log("Chemin avant génération de l'URL signée:",t),!r.ok)throw new Error(`Erreur lors de la génération de l'URL signée: ${r.status}`);const{url:a}=await r.json();console.log("Tentative de chargement du fichier JSON depuis:",a);const n=await fetch(a);if(!n.ok)throw new Error(`Erreur lors du téléchargement du fichier JSON: ${n.status}`);const s=await n.json();return console.log("Contenu du fichier JSON chargé depuis",a,":",s),s}catch(t){throw console.error(`Erreur lors de la récupération du fichier JSON depuis ${e}:`,t),t}}function cleanPath(e){const t=e.split("/"),r=[];for(let e=0;e<t.length;e++)".."===t[e]?r.length&&r.pop():"."!==t[e]&&""!==t[e]&&r.push(t[e]);return r.join("/")}class Router{constructor(e,t){this.dirUrl=e,this.filenameToLink=t}translate(e){if(null!=this.filenameToLink)return this.filenameToLink[e];return`${this.cleanPath(this.dirUrl)}/${e}`}cleanPath(e){const t=e.split("/"),r=[];for(let e=0;e<t.length;e++)".."===t[e]?r.length&&r.pop():"."!==t[e]&&""!==t[e]&&r.push(t[e]);return r.join("/")}}const Format={RED:{numChannels:1},LUMINANCE_ALPHA:{numChannels:2},RGB:{numChannels:3},RGBA:{numChannels:4}},GridTextureSource={RGBA_FROM_RGBA:{format:Format.RGBA,channels:[0,1,2,3]},RGB_FROM_RGBA:{format:Format.RGBA,channels:[0,1,2]},RGB_FROM_RGB:{format:Format.RGB,channels:[0,1,2]},ALPHA_FROM_RGBA:{format:Format.RGBA,channels:[3]},RED_FROM_RED:{format:Format.RED,channels:[0]},LA_FROM_LUMINANCE_ALPHA:{format:Format.LUMINANCE_ALPHA,channels:[0,1]}},GridTextureDestination={RED_IN_RED:{format:Format.RED,channels:[0]},RGB_IN_RGB:{format:Format.RGB,channels:[0,1,2]},RGBA_IN_RGBA:{format:Format.RGBA,channels:[0,1,2,3]},LA_IN_LUMINANCE_ALPHA:{format:Format.LUMINANCE_ALPHA,channels:[0,1]},LUMINANCE_IN_LUMINANCE_ALPHA:{format:Format.LUMINANCE_ALPHA,channels:[0]},ALPHA_IN_LUMINANCE_ALPHA:{format:Format.LUMINANCE_ALPHA,channels:[1]}};let gSceneAccumulate=null,gLowResBlitCamera=null,gHighResBlitCamera=null,gOldMatrixWorld=null,gOldProjectionMatrix=null,gFrameIndex=0,gLowResTexture=null;function createAccumulateMaterial(e,t,r,a){return new THREE.ShaderMaterial({uniforms:{mapLowRes:{value:e},mapHistory:{value:t},lowResolution:{value:r},highResolution:{value:a},jitterOffset:{value:new THREE.Vector2(0,0)},emaAlpha:{value:.15}},vertexShader:accumulateVertexShader,fragmentShader:accumulateFragmentShader})}const gAccumulationTextures=[null,null],normalizeVertexShader="\nvarying vec2 vUv;\nvoid main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n",normalizeFragmentShader="\nvarying vec2 vUv;\nuniform sampler2D map;\nvoid main() {\n gl_FragColor = texture2D(map, vUv);\n if (gl_FragColor.a > 0.0) {\n gl_FragColor.rgb /= gl_FragColor.a;\n }\n gl_FragColor.a = 1.0;\n}\n";function createNormalizeMaterial(e){return new THREE.ShaderMaterial({uniforms:{map:{value:e}},vertexShader:normalizeVertexShader,fragmentShader:normalizeFragmentShader})}let gSceneNormalize=null;const accumulateVertexShader="\nvarying vec2 vUv;\nvoid main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n",accumulateFragmentShader="\nvarying vec2 vUv;\nuniform vec2 lowResolution;\nuniform vec2 highResolution;\nuniform vec2 jitterOffset;\nuniform float emaAlpha;\n\nuniform sampler2D mapLowRes;\nuniform sampler2D mapHistory;\n\nfloat pixelFilter(vec2 pixelCenter, vec2 sampleCenter) {\n vec2 delta = pixelCenter - sampleCenter;\n float squaredNorm = dot(delta, delta);\n return exp(-2.29 * squaredNorm);\n}\n\nvoid main() {\n // First we need to compute the coordinates of the pixel centers\n // in the low resolution grid by compensating for the camera jitter.\n // Note that the offset is defined in clip space [-1,1]^2, so we need\n // to multiply it by 0.5 to make it valid in texture space [0,1]^2.\n vec2 compensatedUnitCoords = vUv - jitterOffset * 0.5;\n\n // Now compute the integer coordinates in the low resolution grid for each\n // adjacent texel.\n ivec2 lowResCoords00 = ivec2(compensatedUnitCoords * lowResolution - 0.5);\n ivec2 lowResCoords01 = ivec2(0, 1) + lowResCoords00;\n ivec2 lowResCoords10 = ivec2(1, 0) + lowResCoords00;\n ivec2 lowResCoords11 = ivec2(1, 1) + lowResCoords00;\n\n float mask00 =\n min(lowResCoords00.x, lowResCoords00.y) < 0 ||\n lowResCoords00.x >= int(lowResolution.x) ||\n lowResCoords00.y >= int(lowResolution.y) ? 0.0 : 1.0;\n float mask01 =\n min(lowResCoords01.x, lowResCoords01.y) < 0 ||\n lowResCoords01.x >= int(lowResolution.x) ||\n lowResCoords01.y >= int(lowResolution.y) ? 0.0 : 1.0;\n float mask10 =\n min(lowResCoords10.x, lowResCoords10.y) < 0 ||\n lowResCoords10.x >= int(lowResolution.x) ||\n lowResCoords10.y >= int(lowResolution.y) ? 0.0 : 1.0;\n float mask11 =\n min(lowResCoords11.x, lowResCoords11.y) < 0 ||\n lowResCoords11.x >= int(lowResolution.x) ||\n lowResCoords11.y >= int(lowResolution.y) ? 0.0 : 1.0;\n\n // We also need to keep track of the high resolution counterparts of these\n // coordinates, so we can compute the pixel reconstruction filter weights.\n vec2 compensatedHighResCoords = highResolution * compensatedUnitCoords;\n vec2 highResCoords00 =\n highResolution * (vec2(lowResCoords00) + 0.5) / lowResolution;\n vec2 highResCoords01 =\n highResolution * (vec2(lowResCoords01) + 0.5) / lowResolution;\n vec2 highResCoords10 =\n highResolution * (vec2(lowResCoords10) + 0.5) / lowResolution;\n vec2 highResCoords11 =\n highResolution * (vec2(lowResCoords11) + 0.5) / lowResolution;\n\n vec4 lowResColor = vec4(0.0, 0.0, 0.0, 0.0);\n lowResColor += mask00 * vec4(\n texelFetch(mapLowRes,lowResCoords00, 0).rgb, 1.0) *\n pixelFilter(compensatedHighResCoords, highResCoords00);\n lowResColor += mask01 * vec4(\n texelFetch(mapLowRes, lowResCoords01, 0).rgb, 1.0) *\n pixelFilter(compensatedHighResCoords, highResCoords01);\n lowResColor += mask10 * vec4(\n texelFetch(mapLowRes, lowResCoords10, 0).rgb, 1.0) *\n pixelFilter(compensatedHighResCoords, highResCoords10);\n lowResColor += mask11 * vec4(\n texelFetch(mapLowRes, lowResCoords11, 0).rgb, 1.0) *\n pixelFilter(compensatedHighResCoords, highResCoords11);\n\n vec4 historyColor = texture2D(mapHistory, vUv);\n gl_FragColor = emaAlpha * lowResColor + (1.0 - emaAlpha) * historyColor;\n}\n";function setupProgressiveRendering(e,t){gHighResBlitCamera=new THREE.OrthographicCamera(e.offsetWidth/-2,e.offsetWidth/2,e.offsetHeight/2,e.offsetHeight/-2,-1e4,1e4),gHighResBlitCamera.position.z=100;let r=new THREE.PlaneBufferGeometry(e.offsetWidth,e.offsetHeight);gLowResTexture=new THREE.WebGLRenderTarget(Math.trunc(e.offsetWidth/t),Math.trunc(e.offsetHeight/t),{minFilter:THREE.NearestFilter,magFilter:THREE.NearestFilter,type:THREE.UnsignedByteType,format:THREE.RGBFormat}),gAccumulationTextures[0]=new THREE.WebGLRenderTarget(e.offsetWidth,e.offsetHeight,{minFilter:THREE.NearestFilter,magFilter:THREE.NearestFilter,type:THREE.FloatType,format:THREE.RGBAFormat}),gAccumulationTextures[1]=new THREE.WebGLRenderTarget(e.offsetWidth,e.offsetHeight,{minFilter:THREE.NearestFilter,magFilter:THREE.NearestFilter,type:THREE.FloatType,format:THREE.RGBAFormat});let a=new THREE.Mesh(r,createAccumulateMaterial(gLowResTexture.texture,gAccumulationTextures[1],new THREE.Vector2(Math.trunc(e.offsetWidth/t),Math.trunc(e.offsetHeight/t)),new THREE.Vector2(e.offsetWidth,e.offsetHeight)));a.position.z=-100,gSceneAccumulate=new THREE.Scene,gSceneAccumulate.add(a),gSceneAccumulate.autoUpdate=!1;let n=new THREE.Mesh(r,createNormalizeMaterial(gAccumulationTextures[0].texture));n.position.z=-100,gSceneNormalize=new THREE.Scene,gSceneNormalize.add(n),gSceneNormalize.autoUpdate=!1,gLowResBlitCamera=new THREE.OrthographicCamera(Math.trunc(e.offsetWidth/t)/-2,Math.trunc(e.offsetWidth/t)/2,Math.trunc(e.offsetHeight/t)/2,Math.trunc(e.offsetHeight/t)/-2,-1e4,1e4),gLowResBlitCamera.position.z=100,gOldProjectionMatrix=gCamera.projectionMatrix.clone(),gOldMatrixWorld=gCamera.matrixWorld.clone()}function renderFrame(e){e||(e=gCamera.projectionMatrix.clone());let t=new THREE.Matrix4;t.getInverse(e);let r=gCamera.matrixWorld;submodel_T_world=gSubmodelTransform,submodel_T_camera=new THREE.Matrix4,submodel_T_camera.multiplyMatrices(submodel_T_world,r);let a=getRayMarchScene();a.children[0].material.uniforms.world_T_cam.value=submodel_T_camera,a.children[0].material.uniforms.cam_T_clip.value=t,a.children[0].material.uniforms.displayMode.value=gDisplayMode-0,gRenderer.clear(),gRenderer.render(a,gLowResBlitCamera)}function renderProgressively(){const e=gAccumulationTextures[0].width/gLowResTexture.width;if(1==e)return void renderFrame();let t=!gCamera.projectionMatrix.equals(gOldProjectionMatrix)||!gCamera.matrixWorld.equals(gOldMatrixWorld);const r=e%2==0;let a=.5,n=Math.trunc(e/2);r||(a=.5,n+=1);let s=[],i=[];for(let t=0;t<n;t++)for(let r=0;r<n;r++)s.push((a+t)/e),i.push((a+r)/e),s.push(-(a+t)/e),i.push((a+r)/e),s.push((a+t)/e),i.push(-(a+r)/e),s.push(-(a+t)/e),i.push(-(a+r)/e);let o=gFrameIndex%s.length,l=s[o],c=i[o];gLowResBlitCamera.left=l+gLowResTexture.width/-2,gLowResBlitCamera.right=l+gLowResTexture.width/2,gLowResBlitCamera.top=c+gLowResTexture.height/2,gLowResBlitCamera.bottom=c+gLowResTexture.height/-2,gLowResBlitCamera.updateProjectionMatrix(),l*=2/gLowResTexture.width,c*=2/gLowResTexture.height;let u=gCamera.projectionMatrix.clone();u.elements[8]+=l,u.elements[9]+=c,gRenderer.setRenderTarget(gLowResTexture),renderFrame(u);let d=Math.min(1,.7/s.length);t&&(gFrameIndex=0,d=1);let p=gFrameIndex%2,g=1-p;gRenderer.setRenderTarget(gAccumulationTextures[p]),gSceneAccumulate.children[0].material.uniforms.mapHistory.value=gAccumulationTextures[g].texture,gSceneAccumulate.children[0].material.uniforms.jitterOffset.value=new THREE.Vector2(l,c),gSceneAccumulate.children[0].material.uniforms.emaAlpha.value=d,gRenderer.clear(),gRenderer.render(gSceneAccumulate,gHighResBlitCamera),gRenderer.setRenderTarget(null),gSceneNormalize.children[0].material.uniforms.map.value=gAccumulationTextures[p].texture,gRenderer.clear(),gRenderer.render(gSceneNormalize,gHighResBlitCamera),gFrameIndex++,gOldProjectionMatrix=gCamera.projectionMatrix.clone(),gOldMatrixWorld=gCamera.matrixWorld.clone()}function computeTrilerpLocationsAndWeights(e,t,r){let a=(new THREE.Vector3).copy(e);a.addScalar(1),a.divideScalar(2),a.multiplyScalar(r),a.subScalar(.5);const n=(new THREE.Vector3).copy(a).floor(),s=(new THREE.Vector3).copy(a).ceil();let i=t.x>0?s.x:n.x,o=t.y>0?s.y:n.y,l=t.z>0?s.z:n.z;i=Math.min(Math.max(i,0),r-1),o=Math.min(Math.max(o,0),r-1),l=Math.min(Math.max(l,0),r-1),i=r-1-i,[o,l]=[l,o];const c=(l*r+o)*r+i;let u=a.x-n.x,d=a.y-n.y,p=a.z-n.z;0==t.x&&(u=1-u),0==t.y&&(d=1-d),0==t.z&&(p=1-p);return[c,u*d*p]}function trilerpDeferredMlpKernel(e,t,r){let a,n,s;if(gDeferredMlp["ResampleDense_"+t+"/kernel"]){const i=gDeferredMlp["ResampleDense_"+t+"/kernel"],o=i.data,l=i.shape[1],c=i.shape[4],u=i.shape[5];a=makeMultipleOf(u,4),n=makeMultipleOf(c,4),s=new Float32Array(n*a);let d=(new THREE.Vector3).copy(r);d.divideScalar(getSubmodelScaleFactor(e));const p=e*l*l*l*c*u;for(let e=0;e<2;e++)for(let t=0;t<2;t++)for(let r=0;r<2;r++){const[i,g]=computeTrilerpLocationsAndWeights(d,new THREE.Vector3(e,t,r),l),m=p+c*u*i;for(let i=0;i<a;i++)for(let a=0;a<n;a++){let l=i*n+a,d=0;a<c&&i<u&&(d=o[m+a*u+i]),e+t+r===0?s[l]=g*d:s[l]+=g*d}}}else{const e=gDeferredMlp["Dense_"+t+"/kernel"],r=e.data,i=e.shape[0],o=e.shape[1];a=makeMultipleOf(o,4),n=makeMultipleOf(i,4),s=new Float32Array(n*a);for(let e=0;e<a;e++)for(let t=0;t<n;t++){t<i&&e<o&&(s[e*n+t]=r[t*o+e])}}let i=new Float32Array(n*a);for(let e=0;e<n;e+=4)for(let t=0;t<a;t++)for(let r=0;r<4;r++)i[e/4*a*4+4*t+r]=s[e/4*4+t*(n/4*4)+r];let o=new THREE.DataTexture(i,1,n*a/4,THREE.RGBAFormat);return o.magFilter=THREE.NearestFilter,o.minFilter=THREE.NearestFilter,o.type=THREE.FloatType,o}function trilerpDeferredMlpBiases(e,t,r){let a;if(gDeferredMlp["ResampleDense_"+t+"/bias"]){const n=gDeferredMlp["ResampleDense_"+t+"/bias"],s=n.data,i=n.shape[1],o=n.shape[4],l=makeMultipleOf(o,4);a=new Array(l/4);let c=(new THREE.Vector3).copy(r);c.divideScalar(getSubmodelScaleFactor(e));const u=e*i*i*i*o;for(let e=0;e<2;e++)for(let t=0;t<2;t++)for(let r=0;r<2;r++){const[n,d]=computeTrilerpLocationsAndWeights(c,new THREE.Vector3(e,t,r),i),p=u+o*n;for(let n=0;n<l/4;++n){let i=new THREE.Vector4(0,0,0,0);for(let e=0;e<4;e++)4*n+0<l&&i.setComponent(e,s[p+4*n+e]);i.multiplyScalar(d),e+t+r===0?a[n]=i:a[n].add(i)}}}else{const e=gDeferredMlp["Dense_"+t+"/bias"],r=e.data,n=makeMultipleOf(e.shape[0],4);a=new Array(n/4);for(let e=0;e<n/4;++e){let t=new THREE.Vector4(0,0,0,0);for(let a=0;a<4;a++)4*e+0<n&&t.setComponent(a,r[4*e+a]);a[e]=t}}return a}function rewriteViewDependenceDefinitions(e,t){let r=getDeferredMlp();const a=r["ResampleDense_0/kernel"]?"ResampleDense_":"Dense_",n=r["ResampleDense_0/kernel"]?4:0;let s=t,i=["intermediate_one","intermediate_two","result"];for(let e=0;e<3;e++){let t=r[a+e+"/bias"].shape[n],o=`bias_${e}`,l=i[e],c=[];for(let e=0;e<t/4;e++)c.push(`${l}[${e}] = ${o}[${e}];`);let u=c.join(" ")+"\n";s=s.replace(new RegExp(`INITIALIZE_OUTPUT_ACTIVATIONS_${e}`,"g"),u)}let o=makeMultipleOf(r[a+"0/kernel"].shape[n],4),l=makeMultipleOf(r[a+"0/bias"].shape[n],4),c=makeMultipleOf(r[a+"1/bias"].shape[n],4),u=makeMultipleOf(r[a+"2/bias"].shape[n],4);return s=s.replace(new RegExp("NUM_CHANNELS_ZERO","g"),o),s=s.replace(new RegExp("NUM_POSENC_SCALES","g"),4..toString()),s=s.replace(new RegExp("NUM_CHANNELS_ONE","g"),l),s=s.replace(new RegExp("NUM_CHANNELS_TWO","g"),c),s=s.replace(new RegExp("NUM_CHANNELS_THREE","g"),u),s}function makeMultipleOf(e,t){return e%t==0?e:e+t-e%t}function setupInitialCameraPose(e,t){function r(e){var r,a,n;gCamera.position.x=e.position[0]+t.x,gCamera.position.y=e.position[1]+t.y,gCamera.position.z=e.position[2]+t.z,r=e.lookat[0]+t.x,a=e.lookat[1]+t.y,n=e.lookat[2]+t.z,gOrbitControls?(gOrbitControls.target.x=r,gOrbitControls.target.y=a,gOrbitControls.target.z=n):gMapControls?(gMapControls.target.x=gCamera.position.x+(r-gCamera.position.x)*gCamera.near,gMapControls.target.y=gCamera.position.y+(a-gCamera.position.y)*gCamera.near,gMapControls.target.z=gCamera.position.z+(n-gCamera.position.z)*gCamera.near):gCamera.lookAt(r,a,n)}initialPoses={default:{position:[0,0,0],lookat:[0,0,1]},gardenvase:{position:[-1.1868985500525444,.1898527233835131,-.04923970470097733],lookat:[-.05581392405861873,-.40202760746449473,.02985343723310108]},stump:{position:[0,.4,-.8],lookat:[0,-.3,0]},flowerbed:{position:[-.02402388218043944,.11825367482140309,.907525093384825],lookat:[.016306507293821822,-.15676691106539536,-.016192691610482132]},treehill:{position:[-.70994804046872,.19435986647308223,.30833533637897453],lookat:[.06327294888291587,-.13299740290200024,.0037554887097183934]},bicycle:{position:[-.4636408064933045,.49624791762954734,.8457540259646037],lookat:[.017170160491904368,-.24649043500978007,-.07787524806850904]},kitchenlego:{position:[-.5872864419408019,.05633623000443683,-.9472239198227385],lookat:[.07177184299031553,-.4020277194862108,.04850453170234236]},fulllivingroom:{position:[1.1539572663654272,-.006785278327404387,-.0972986385811351],lookat:[-.05581392405861873,-.40202760746449473,.02985343723310108]},kitchencounter:{position:[-.7006764413546107,.2255633917824672,-.46941182833135847],lookat:[.13197415755218864,-.4020278046227117,.09221809216932579]},officebonsai:{position:[-.4773314920559294,.05409730603092788,1.014304107335418],lookat:[.11970974858222336,-.40426664345968033,-.019801655674420764]}},r(initialPoses.default);for(let t in initialPoses)if(e.includes(t)){r(initialPoses[t]);break}gCamera.updateProjectionMatrix()}let gOrbitControls=null,gMapControls=null,gPointerLockControls=null,gKeyW=!1,gKeyA=!1,gKeyS=!1,gKeyD=!1,gKeyQ=!1,gKeyE=!1,gKeyShift=!1;const gClock=new THREE.Clock;function addHandlers(){let e=document.getElementById("shader-editor");document.addEventListener("keypress",(function(t){if("input"!==document.activeElement.tagName.toLowerCase()&&"textarea"!==document.activeElement.tagName.toLowerCase()&&document.activeElement!==e){if(32!==t.keyCode&&" "!==t.key&&"Spacebar"!==t.key||(gDisplayMode==DisplayModeType.DISPLAY_NORMAL?(gDisplayMode=DisplayModeType.DISPLAY_DIFFUSE,console.log("Displaying DIFFUSE")):gDisplayMode==DisplayModeType.DISPLAY_DIFFUSE?(gDisplayMode=DisplayModeType.DISPLAY_FEATURES,console.log("Displaying DISPLAY_FEATURES")):gDisplayMode==DisplayModeType.DISPLAY_FEATURES?(gDisplayMode=DisplayModeType.DISPLAY_VIEW_DEPENDENT,console.log("Displaying DISPLAY_VIEW_DEPENDENT")):gDisplayMode==DisplayModeType.DISPLAY_VIEW_DEPENDENT?(gDisplayMode=DisplayModeType.DISPLAY_COARSE_GRID,console.log("Displaying DISPLAY_COARSE_GRID")):(gDisplayMode=DisplayModeType.DISPLAY_NORMAL,console.log("Displaying DISPLAY_NORMAL")),t.preventDefault()),"r"===t.key){console.log("Recompile shader.");let r=getRayMarchScene().children[0].material;r.fragmentShader=e.value,r.needsUpdate=!0,t.preventDefault()}if("?"===t.key){let e=gCamera.getWorldPosition(new THREE.Vector3(0,0,0)),r=gCamera.getWorldQuaternion(new THREE.Quaternion);console.log(`\n// Camera Info:\ngCamera.position.set(${e.x}, ${e.y}, ${e.z});\ngCamera.quaternion.set(${r.x}, ${r.y}, ${r.z}, ${r.w});\n`),t.preventDefault()}}})),document.addEventListener("keydown",(function(t){if("input"===document.activeElement.tagName.toLowerCase()||"textarea"===document.activeElement.tagName.toLowerCase())return;if(document.activeElement===e)return;let r=t.key.toLowerCase();"w"===r&&(gKeyW=!0,t.preventDefault()),"a"===r&&(gKeyA=!0),"s"===r&&(gKeyS=!0,t.preventDefault()),"d"===r&&(gKeyD=!0,t.preventDefault()),"q"===r&&(gKeyQ=!0,t.preventDefault()),"e"===r&&(gKeyE=!0,t.preventDefault()),"Shift"===t.key&&(gKeyShift=!0,t.preventDefault())})),document.addEventListener("keyup",(function(t){if("input"===document.activeElement.tagName.toLowerCase()||"textarea"===document.activeElement.tagName.toLowerCase())return;if(document.activeElement===e)return;let r=t.key.toLowerCase();"w"===r&&(gKeyW=!1,t.preventDefault()),"a"===r&&(gKeyA=!1),"s"===r&&(gKeyS=!1,t.preventDefault()),"d"===r&&(gKeyD=!1,t.preventDefault()),"q"===r&&(gKeyQ=!1,t.preventDefault()),"e"===r&&(gKeyE=!1,t.preventDefault()),"Shift"===t.key&&(gKeyShift=!1,t.preventDefault())}))}function setupCameraControls(e,t){if(e&&"fps"==e){gPointerLockControls=new THREE.PointerLockControls(gCamera,t);let e=document.createElement("button");e.innerHTML="Commencer la visite !",e.classList.add("mouse-navigation-button"),e.addEventListener("click",(function(){gPointerLockControls.lock(),gPointerLockControls.connect(),e.classList.add("hidden")}),!1),gPointerLockControls.addEventListener("unlock",(function(){e.classList.remove("hidden")})),t.appendChild(e)}else e&&"map"==e?(gMapControls=new THREE.OrbitControls(gCamera,t),gMapControls.panSpeed=.5/gCamera.near,gMapControls.enableZoom=!1,gMapControls.screenSpacePanning=!1,gMapControls.mouseButtons={LEFT:THREE.MOUSE.ROTATE,RIGHT:THREE.MOUSE.PAN},gMapControls.touches={ONE:THREE.TOUCH.PAN,TWO:THREE.TOUCH.DOLLY_ROTATE}):(gOrbitControls=new THREE.OrbitControls(gCamera,t),gOrbitControls.screenSpacePanning=!0,gOrbitControls.zoomSpeed=.5)}function updateCameraControls(){if(gOrbitControls)gOrbitControls.update();else if(gMapControls)gMapControls.update();else if(gPointerLockControls){const e=gClock.getDelta();let t=.25;gKeyShift&&(t=1);let r=gCamera.getWorldDirection(new THREE.Vector3(0,0,0)),a=new THREE.Vector3(0,1,0);gKeyW&&(gCamera.position=gCamera.position.addScaledVector(r,e*t)),gKeyA&&gPointerLockControls.moveRight(-e*t),gKeyS&&(gCamera.position=gCamera.position.addScaledVector(r,-e*t)),gKeyD&&gPointerLockControls.moveRight(e*t),gKeyQ&&(gCamera.position=gCamera.position.addScaledVector(a,-e*t)),gKeyE&&(gCamera.position=gCamera.position.addScaledVector(a,e*t))}}let gIsCoolingDown=!1,gBenchmarkTimestamps=null,gFrameTimes=[],gBenchmarkCameras={},gBenchmarkCameraIndex=0;const gBenchmarkMethodName="blockmerf";let gBenchmarkSceneName=null,gSaveBenchmarkFrames=!1;function setupBenchmarkStats(e,t){gBenchmarkSceneName=e,gSaveBenchmarkFrames=t;let r=document.getElementById("benchmark-stats");r.style.display="block",r.addEventListener("click",(e=>{gBenchmark=!0}))}function clearBenchmarkStats(e){document.getElementById("benchmark-stats").innerHTML=""}function addBenchmarkRow(e){document.getElementById("benchmark-stats").innerHTML+=e+"\n"}function getBenchmarkStats(e){return document.getElementById("benchmark-stats").innerHTML}function loadBenchmarkCameras(e){const t=e.translate("test_frames.json"),r=loadJSONFile(t);r.catch((e=>{console.error("Could not load test frames from: "+t+", error: "+e)})),r.then((e=>{gBenchmarkCameras=e.test_frames}))}function setBenchmarkCameraPose(e,t){e.position.fromArray(gBenchmarkCameras[t].position),e.setRotationFromMatrix((new THREE.Matrix4).fromArray(gBenchmarkCameras[t].rotation)),e.projectionMatrix.fromArray(gBenchmarkCameras[t].projection)}function cooldownFrame(e){const t=.5*(1+Math.sin(e*Math.PI/1e3));let r=new THREE.Color("#FFFFFF");r.lerp(new THREE.Color("#A5C0E2"),t),gRenderer.setClearColor(r,1),gRenderer.clear(),gStats&&gStats.update(),gIsCoolingDown&&requestAnimationFrame(cooldownFrame)}function formatTimestampAsString(){const e=new Date,t=e.getHours().toString().padStart(2,"0"),r=e.getMinutes().toString().padStart(2,"0");return`${e.getFullYear()}_${e.getMonth()+1}_${e.getDate()}_${t}${r}`}function benchmarkPerformance(e){const t=Math.max(4,Math.ceil(100/gFrameMult)),r=Math.max(2,Math.ceil(.1*t));if(isLoading())return e;if(!gBenchmarkTimestamps&&!gIsCoolingDown){setBenchmarkCameraPose(gCamera,0),gBenchmarkTimestamps=[];let t=new THREE.Vector2;return gRenderer.getSize(t),clearBenchmarkStats(),addBenchmarkRow(`frame timestamps (ms) at ${t.x}x${t.y}`),addBenchmarkRow("cam_idx ; start ; end ; mean frame time"),e}if(gBenchmarkTimestamps.push(window.performance.now()),gBenchmarkTimestamps.length<t)return e;gSaveBenchmarkFrames&&(frameAsPng=gRenderer.domElement.toDataURL("image/png"),saveAs(frameAsPng,digits(gBenchmarkCameraIndex,4)+".png"));let a=gBenchmarkTimestamps.slice(r);const n=a.length,s=a[0],i=a.pop();let o=(i-s)/(gFrameMult*(n-1));if(gFrameTimes.push(o),addBenchmarkRow(`${gBenchmarkCameraIndex} ; ${s} ; ${i} ; ${o}`),++gBenchmarkCameraIndex>=gBenchmarkCameras.length){console.log(gFrameTimes.reduce(((e,t)=>e+t),0)/gFrameTimes.length),gBenchmark=!1;const t=new Blob([getBenchmarkStats()],{type:"text/plain;charset=utf-8"}),r="blockmerf_"+gBenchmarkSceneName+"_frameMult_"+gFrameMult+"_"+formatTimestampAsString()+".csv";return saveAs(t,r),e}return gBenchmarkTimestamps=[],setBenchmarkCameraPose(gCamera,gBenchmarkCameraIndex),e}let gSubmodelPanel=null,gVMemPanel=null,gStepMult=1,gExposure=null;function loadScene(e,t){let r;e&&e.includes(".json")?r=loadJSONFile(e):(r=Promise.resolve(null),console.error("dirUrl est null ou non valide. Le fichier Json est dans le dossier")),r.then((r=>{const a=new Router(e,r);console.log("router:",a);const n=a.translate("scene_params.json");console.log("sceneParamsUrl:",n);const s=loadJSONFile(n);return console.log("sceneParamsPromise:",s),t.loadBenchmarkCameras&&loadBenchmarkCameras(a),Promise.all([s,{router:a,filenameToLink:r}])})).then((e=>{const[t,r]=e;let a=0;gUseSubmodel=t.hasOwnProperty("num_local_submodels")&&t.num_local_submodels>1,gUseSubmodel&&(gSubmodelCount=t.num_local_submodels,a=t.sm_to_params[t.submodel_idx]);let n=[];for(let e=0;e<gSubmodelCount;++e){const a=t.params_to_sm[e],s=r.router.translate(submodelAssetPath(a,"scene_params.json"));n.push(loadJSONFile(s))}return Promise.all([{...r,initialSubmodelIndex:a},...n])})).then((r=>{let[a,...n]=r;for(let r=0;r<n.length;++r){n[r]=extend(n[r],t);const s=n[r].params_to_sm[r];let i=e;gUseSubmodel&&(i=`${i}/${submodelAssetPath(s)}`);let o=new Router(i,a.filenameToLink),l=initializeSceneContent(n[r],o);console.log(`spec for submodel #${r}:`,l.spec),registerSubmodelContent(r,l)}let s=a.initialSubmodelIndex;return setupInitialCameraPose(e,submodelCenter(s,getSubmodelContent(s).params)),Promise.all([s,initializeDeferredMlp(s)])})).then((([e,t])=>initializePingPongBuffers(e))).then((()=>requestAnimationFrame(renderNextFrame)))}let disableCameraControls=!1;function initFromParameters(){const e=new URL(window.location.href).searchParams;console.log(e);const t="nyc/sm_004";console.log(t);let r=e.get("quality"),a=parseInt(e.get("downscale")||1,10);const n=e.get("stepMult");n&&(gStepMult=parseInt(n,10));const s=e.get("frameMult");s&&(gFrameMult=parseInt(s,10));const i=e.get("exposure");i&&(gExposure=parseFloat(i));let o={};const l=e.get("benchmark");if(l&&("time"===l.toLowerCase()||"quality"===l.toLowerCase())){o.loadBenchmarkCameras=!0,r="high";const e=t.split("/").slice(-2);setupBenchmarkStats(e[0]+"_"+e[1],"quality"===l.toLowerCase())}const c=e.get("deferredMode");c&&(o.deferred_rendering_mode=c);const u=e.get("combineMode");u&&"concat_and_sum"===u&&(o.merge_features_combine_op="coarse_sum");const d=e.get("useBits");d&&(o.useBits="true"===d.toLowerCase());const p=e.get("useDistanceGrid");p&&(o.useDistanceGrid="true"===p.toLowerCase());const g=e.get("legacyGrids");g&&(o.legacyGrids="true"===g.toLowerCase());const m=e.get("activation");m&&(o.activation=m);const h=e.get("featureGating");h&&(o.feature_gating="true"===h.toLowerCase());const f=e.get("submodelCacheSize");f&&(gSubmodelCacheSize=Number(f));const y=e.get("mergeSlices");y&&(o.merge_slices="true"==y);const _=e.get("backgroundColor");_&&(o.backgroundColor="#"+_);const T=document.createElement("div");T.classList.add("view");document.getElementById("viewspacecontainer").appendChild(T);const{width:x,height:S}=function(e){const t=getComputedStyle(e);return{width:parseInt(t.width,10),height:parseInt(t.height,10)}}(T);T.style.width=`${x}px`,T.style.height=`${S}px`,console.log("Width:",x,"Height:",S);const R=e.get("mouseMode")||"orbit";let E=.99;if(!e.get("downscale")&&r){let e=x*S;for("phone"==r?(e=135e3,E=.8):"low"==r?(e=15e4,E=.8):"medium"==r&&(e=768e3,E=.95);x*S/a>e;)a++;console.log("Automatically chose a downscaling factor of "+a)}o.useLargerStepsWhenOccluded=!1,o.step_size_visibility_delay=E;const b=parseFloat(e.get("near")||.01),C=parseFloat(e.get("vfovy")||40),w=document.querySelector(".viewspace");w.textContent="",w.appendChild(T);let A=document.createElement("canvas");T.appendChild(A),A.style.width="100%",A.style.height="100%",A.style.border=getComputedStyle(T).border,A.style.borderRadius=getComputedStyle(T).borderRadius,A.style.boxSizing=getComputedStyle(T).boxSizing,gStats=Stats(),gStats.dom.style.position="absolute",gStats.dom.style.display="none",w.appendChild(gStats.dom),gSubmodelPanel=gStats.addPanel(new Stats.Panel("SM","#0ff","#002")),gSubmodelPanel.update(getActiveSubmodelIndex()),gVMemPanel=gStats.addPanel(new Stats.Panel("MB VRAM","#0ff","#002")),gVMemPanel.update(0),gStats.showPanel(0);let v=A.getContext("webgl2",{powerPreference:"high-performance",alpha:!1,stencil:!0,precision:"highp",depth:!0,antialias:!1,desynchronized:!1,preserveDrawingBuffer:l&&"quality"===l.toLowerCase()});v.enable(v.DEPTH_TEST),v.depthFunc(v.LEQUAL),v.pixelStorei(v.UNPACK_ALIGNMENT,1),v.viewport(0,0,A.width,A.height),gRenderer=new THREE.WebGLRenderer({canvas:A,context:v}),gCamera=new THREE.PerspectiveCamera(C,Math.trunc(T.offsetWidth/a)/Math.trunc(T.offsetHeight/a),b,2e3),gCamera.updateProjectionMatrix(),window.sceneCamera=gCamera,setupProgressiveRendering(T,a),gRenderer.autoClear=!1,gRenderer.setSize(T.offsetWidth,T.offsetHeight),gRenderer.setClearColor(0,1),setupCameraControls(R,T),setupViewport(Math.trunc(T.offsetWidth/a),Math.trunc(T.offsetHeight/a)),loadScene(t,o)}let sphereAdded=!1;function renderNextFrame(e){garbageCollectSubmodelPayloads();let t=positionToSubmodel(gCamera.position,getActiveSubmodelContent().params);setCurrentRayMarchScene(t),t=getActiveSubmodelIndex();let r=getSubmodelContent(t).params;for(let e=0;e<gFrameMult;++e){gSubmodelTransform=submodelTransform(t,r),gSubmodelPanel.update(t),gVMemPanel.update(getCurrentTextureUsageInBytes()/1e6),disableCameraControls||updateCameraControls(),gBenchmark||gCamera.updateProjectionMatrix(),gCamera.updateMatrixWorld();const e=submodelCenter(t,r),a=getSubmodelScale(t);let n=(new THREE.Vector3).copy(gCamera.position);n.sub(e),n.multiplyScalar(a);let s=getRayMarchScene().children[0].material.uniforms;s.weightsZero.value&&s.weightsZero.value.dispose(),s.weightsOne.value&&s.weightsOne.value.dispose(),s.weightsTwo.value&&s.weightsTwo.value.dispose(),s.bias_0.value=trilerpDeferredMlpBiases(t,0,n),s.bias_1.value=trilerpDeferredMlpBiases(t,1,n),s.bias_2.value=trilerpDeferredMlpBiases(t,2,n),s.weightsZero.value=trilerpDeferredMlpKernel(t,0,n),s.weightsOne.value=trilerpDeferredMlpKernel(t,1,n),s.weightsTwo.value=trilerpDeferredMlpKernel(t,2,n),gRenderer.clear(),renderProgressively(),gRenderer.render(gSphereScene,gCamera)}gStats.update();let a=()=>{requestAnimationFrame(renderNextFrame)};gBenchmark&&(a=benchmarkPerformance(a)),a()}function start(){initFromParameters(),addHandlers(),gCamera&&gRenderer?(addInteractionPlane(),setupNewPlaneGizmo(newPlane),setupMouseHover(),window.addEventListener("mousemove",onMouseMove,!1),window.addEventListener("mousedown",onMouseDown,!1),window.addEventListener("mouseup",onMouseUp,!1)):console.error("gCamera ou gRenderer non initialisés.")}window.onload=start;
.history/combined.min_20241120000010.js ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ //# sourceMappingURL=combined.min.js.map
2
+ let DecodeStream=function(){function e(){this.pos=0,this.bufferLength=0,this.eof=!1,this.buffer=null}return e.prototype={ensureBuffer:function(e){var t=this.buffer,r=t?t.byteLength:0;if(e<r)return t;for(var a=512;a<e;)a<<=1;for(var n=new Uint8Array(a),s=0;s<r;++s)n[s]=t[s];return this.buffer=n},getByte:function(){for(var e=this.pos;this.bufferLength<=e;){if(this.eof)return null;this.readBlock()}return this.buffer[this.pos++]},getBytes:function(e){var t=this.pos;if(e){this.ensureBuffer(t+e);for(var r=t+e;!this.eof&&this.bufferLength<r;)this.readBlock();var a=this.bufferLength;r>a&&(r=a)}else{for(;!this.eof;)this.readBlock();r=this.bufferLength}return this.pos=r,this.buffer.subarray(t,r)},lookChar:function(){for(var e=this.pos;this.bufferLength<=e;){if(this.eof)return null;this.readBlock()}return String.fromCharCode(this.buffer[this.pos])},getChar:function(){for(var e=this.pos;this.bufferLength<=e;){if(this.eof)return null;this.readBlock()}return String.fromCharCode(this.buffer[this.pos++])},makeSubStream:function(e,t,r){for(var a=e+t;this.bufferLength<=a&&!this.eof;)this.readBlock();return new Stream(this.buffer,e,t,r)},skip:function(e){e||(e=1),this.pos+=e},reset:function(){this.pos=0}},e}(),FlateStream=function(){var e=new Uint32Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),t=new Uint32Array([3,4,5,6,7,8,9,10,65547,65549,65551,65553,131091,131095,131099,131103,196643,196651,196659,196667,262211,262227,262243,262259,327811,327843,327875,327907,258,258,258]),r=new Uint32Array([1,2,3,4,65541,65543,131081,131085,196625,196633,262177,262193,327745,327777,393345,393409,459009,459137,524801,525057,590849,591361,657409,658433,724993,727041,794625,798721,868353,876545]),a=[new Uint32Array([459008,524368,524304,524568,459024,524400,524336,590016,459016,524384,524320,589984,524288,524416,524352,590048,459012,524376,524312,589968,459028,524408,524344,590032,459020,524392,524328,59e4,524296,524424,524360,590064,459010,524372,524308,524572,459026,524404,524340,590024,459018,524388,524324,589992,524292,524420,524356,590056,459014,524380,524316,589976,459030,524412,524348,590040,459022,524396,524332,590008,524300,524428,524364,590072,459009,524370,524306,524570,459025,524402,524338,590020,459017,524386,524322,589988,524290,524418,524354,590052,459013,524378,524314,589972,459029,524410,524346,590036,459021,524394,524330,590004,524298,524426,524362,590068,459011,524374,524310,524574,459027,524406,524342,590028,459019,524390,524326,589996,524294,524422,524358,590060,459015,524382,524318,589980,459031,524414,524350,590044,459023,524398,524334,590012,524302,524430,524366,590076,459008,524369,524305,524569,459024,524401,524337,590018,459016,524385,524321,589986,524289,524417,524353,590050,459012,524377,524313,589970,459028,524409,524345,590034,459020,524393,524329,590002,524297,524425,524361,590066,459010,524373,524309,524573,459026,524405,524341,590026,459018,524389,524325,589994,524293,524421,524357,590058,459014,524381,524317,589978,459030,524413,524349,590042,459022,524397,524333,590010,524301,524429,524365,590074,459009,524371,524307,524571,459025,524403,524339,590022,459017,524387,524323,589990,524291,524419,524355,590054,459013,524379,524315,589974,459029,524411,524347,590038,459021,524395,524331,590006,524299,524427,524363,590070,459011,524375,524311,524575,459027,524407,524343,590030,459019,524391,524327,589998,524295,524423,524359,590062,459015,524383,524319,589982,459031,524415,524351,590046,459023,524399,524335,590014,524303,524431,524367,590078,459008,524368,524304,524568,459024,524400,524336,590017,459016,524384,524320,589985,524288,524416,524352,590049,459012,524376,524312,589969,459028,524408,524344,590033,459020,524392,524328,590001,524296,524424,524360,590065,459010,524372,524308,524572,459026,524404,524340,590025,459018,524388,524324,589993,524292,524420,524356,590057,459014,524380,524316,589977,459030,524412,524348,590041,459022,524396,524332,590009,524300,524428,524364,590073,459009,524370,524306,524570,459025,524402,524338,590021,459017,524386,524322,589989,524290,524418,524354,590053,459013,524378,524314,589973,459029,524410,524346,590037,459021,524394,524330,590005,524298,524426,524362,590069,459011,524374,524310,524574,459027,524406,524342,590029,459019,524390,524326,589997,524294,524422,524358,590061,459015,524382,524318,589981,459031,524414,524350,590045,459023,524398,524334,590013,524302,524430,524366,590077,459008,524369,524305,524569,459024,524401,524337,590019,459016,524385,524321,589987,524289,524417,524353,590051,459012,524377,524313,589971,459028,524409,524345,590035,459020,524393,524329,590003,524297,524425,524361,590067,459010,524373,524309,524573,459026,524405,524341,590027,459018,524389,524325,589995,524293,524421,524357,590059,459014,524381,524317,589979,459030,524413,524349,590043,459022,524397,524333,590011,524301,524429,524365,590075,459009,524371,524307,524571,459025,524403,524339,590023,459017,524387,524323,589991,524291,524419,524355,590055,459013,524379,524315,589975,459029,524411,524347,590039,459021,524395,524331,590007,524299,524427,524363,590071,459011,524375,524311,524575,459027,524407,524343,590031,459019,524391,524327,589999,524295,524423,524359,590063,459015,524383,524319,589983,459031,524415,524351,590047,459023,524399,524335,590015,524303,524431,524367,590079]),9],n=[new Uint32Array([327680,327696,327688,327704,327684,327700,327692,327708,327682,327698,327690,327706,327686,327702,327694,0,327681,327697,327689,327705,327685,327701,327693,327709,327683,327699,327691,327707,327687,327703,327695,0]),5];function s(e){throw new Error(e)}function i(e){var t=0,r=e[t++],a=e[t++];-1!=r&&-1!=a||s("Invalid header in flate stream"),8!=(15&r)&&s("Unknown compression method in flate stream"),((r<<8)+a)%31!=0&&s("Bad FCHECK in flate stream"),32&a&&s("FDICT bit set in flate stream"),this.bytes=e,this.bytesPos=2,this.codeSize=0,this.codeBuf=0,DecodeStream.call(this)}return i.prototype=Object.create(DecodeStream.prototype),i.prototype.getBits=function(e){for(var t,r=this.codeSize,a=this.codeBuf,n=this.bytes,i=this.bytesPos;r<e;)void 0===(t=n[i++])&&s("Bad encoding in flate stream"),a|=t<<r,r+=8;return t=a&(1<<e)-1,this.codeBuf=a>>e,this.codeSize=r-=e,this.bytesPos=i,t},i.prototype.getCode=function(e){for(var t=e[0],r=e[1],a=this.codeSize,n=this.codeBuf,i=this.bytes,o=this.bytesPos;a<r;){var l;void 0===(l=i[o++])&&s("Bad encoding in flate stream"),n|=l<<a,a+=8}var c=t[n&(1<<r)-1],u=c>>16,d=65535&c;return(0==a||a<u||0==u)&&s("Bad encoding in flate stream"),this.codeBuf=n>>u,this.codeSize=a-u,this.bytesPos=o,d},i.prototype.generateHuffmanTable=function(e){for(var t=e.length,r=0,a=0;a<t;++a)e[a]>r&&(r=e[a]);for(var n=1<<r,s=new Uint32Array(n),i=1,o=0,l=2;i<=r;++i,o<<=1,l<<=1)for(var c=0;c<t;++c)if(e[c]==i){var u=0,d=o;for(a=0;a<i;++a)u=u<<1|1&d,d>>=1;for(a=u;a<n;a+=l)s[a]=i<<16|c;++o}return[s,r]},i.prototype.readBlock=function(){function i(e,t,r,a,n){for(var s=e.getBits(r)+a;s-- >0;)t[m++]=n}var o=this.getBits(3);if(1&o&&(this.eof=!0),0!=(o>>=1)){var l,c;if(1==o)l=a,c=n;else if(2==o){for(var u=this.getBits(5)+257,d=this.getBits(5)+1,p=this.getBits(4)+4,g=Array(e.length),m=0;m<p;)g[e[m++]]=this.getBits(3);for(var h=this.generateHuffmanTable(g),f=0,y=(m=0,u+d),_=new Array(y);m<y;){var T=this.getCode(h);16==T?i(this,_,2,3,f):17==T?i(this,_,3,3,f=0):18==T?i(this,_,7,11,f=0):_[m++]=f=T}l=this.generateHuffmanTable(_.slice(0,u)),c=this.generateHuffmanTable(_.slice(u,y))}else s("Unknown block type in flate stream");for(var x=(M=this.buffer)?M.length:0,S=this.bufferLength;;){var R=this.getCode(l);if(R<256)S+1>=x&&(x=(M=this.ensureBuffer(S+1)).length),M[S++]=R;else{if(256==R)return void(this.bufferLength=S);var E=(R=t[R-=257])>>16;E>0&&(E=this.getBits(E));f=(65535&R)+E;R=this.getCode(c),(E=(R=r[R])>>16)>0&&(E=this.getBits(E));var b=(65535&R)+E;S+f>=x&&(x=(M=this.ensureBuffer(S+f)).length);for(var C=0;C<f;++C,++S)M[S]=M[S-b]}}}else{var w,A=this.bytes,v=this.bytesPos;void 0===(w=A[v++])&&s("Bad block header in flate stream");var G=w;void 0===(w=A[v++])&&s("Bad block header in flate stream"),G|=w<<8,void 0===(w=A[v++])&&s("Bad block header in flate stream");var P=w;void 0===(w=A[v++])&&s("Bad block header in flate stream"),(P|=w<<8)!=(65535&~G)&&s("Bad uncompressed block length in flate stream"),this.codeBuf=0,this.codeSize=0;var D=this.bufferLength,M=this.ensureBuffer(D+G),k=D+G;this.bufferLength=k;for(var F=D;F<k;++F){if(void 0===(w=A[v++])){this.eof=!0;break}M[F]=w}this.bytesPos=v}},i}(),PNG=function(){class e{static load(t,r,a){"function"==typeof r&&(a=r);const n=new XMLHttpRequest;return n.open("GET",t,!0),n.responseType="arraybuffer",n.onload=()=>{const t=new Uint8Array(n.response||n.mozResponseArrayBuffer),s=new e(t);return"function"==typeof(r&&r.getContext)&&s.render(r),"function"==typeof a?a(s):void 0},n.send(null)}constructor(e){let t;this.data=e,this.pos=8,this.palette=[],this.imgData=[],this.transparency={},this.animation=null,this.text={};let r=null;for(;;){var a;let e=this.readUInt32(),d="";for(t=0;t<4;t++)d+=String.fromCharCode(this.data[this.pos++]);switch(d){case"IHDR":this.width=this.readUInt32(),this.height=this.readUInt32(),this.bits=this.data[this.pos++],this.colorType=this.data[this.pos++],this.compressionMethod=this.data[this.pos++],this.filterMethod=this.data[this.pos++],this.interlaceMethod=this.data[this.pos++];break;case"acTL":this.animation={numFrames:this.readUInt32(),numPlays:this.readUInt32()||1/0,frames:[]};break;case"PLTE":this.palette=this.read(e);break;case"fcTL":r&&this.animation.frames.push(r),this.pos+=4,r={width:this.readUInt32(),height:this.readUInt32(),xOffset:this.readUInt32(),yOffset:this.readUInt32()};var n=this.readUInt16(),s=this.readUInt16()||100;r.delay=1e3*n/s,r.disposeOp=this.data[this.pos++],r.blendOp=this.data[this.pos++],r.data=[];break;case"IDAT":case"fdAT":for("fdAT"===d&&(this.pos+=4,e-=4),a=r&&r.data||this.imgData,t=0;t<e;t++)a.push(this.data[this.pos++]);break;case"tRNS":switch(this.transparency={},this.colorType){case 3:this.transparency.indexed=this.read(e);var i=255-this.transparency.indexed.length;if(i>0)for(t=0;t<i;t++)this.transparency.indexed.push(255);break;case 0:this.transparency.grayscale=this.read(e)[0];break;case 2:this.transparency.rgb=this.read(e)}break;case"tEXt":var o=this.read(e),l=o.indexOf(0),c=String.fromCharCode.apply(String,o.slice(0,l));this.text[c]=String.fromCharCode.apply(String,o.slice(l+1));break;case"IEND":switch(r&&this.animation.frames.push(r),this.colorType){case 0:case 3:case 4:this.colors=1;break;case 2:case 6:this.colors=3}this.hasAlphaChannel=[4,6].includes(this.colorType);var u=this.colors+(this.hasAlphaChannel?1:0);switch(this.pixelBitlength=this.bits*u,this.colors){case 1:this.colorSpace="DeviceGray";break;case 3:this.colorSpace="DeviceRGB"}return void(this.imgData=new Uint8Array(this.imgData));default:this.pos+=e}if(this.pos+=4,this.pos>this.data.length)throw new Error("Incomplete or corrupt PNG file")}}read(e){const t=new Array(e);for(let r=0;r<e;r++)t[r]=this.data[this.pos++];return t}readUInt32(){return this.data[this.pos++]<<24|this.data[this.pos++]<<16|this.data[this.pos++]<<8|this.data[this.pos++]}readUInt16(){return this.data[this.pos++]<<8|this.data[this.pos++]}decodePixels(e){if(null==e&&(e=this.imgData),0===e.length)return new Uint8Array(0);e=(e=new FlateStream(e)).getBytes();const{width:t,height:r}=this,a=this.pixelBitlength/8,n=new Uint8Array(t*r*a),{length:s}=e;let i=0;function o(o,l,c,u,d=!1){const p=Math.ceil((t-o)/c),g=Math.ceil((r-l)/u),m=a*p,h=d?n:new Uint8Array(m*g);let f=0,y=0;for(;f<g&&i<s;){var _,T,x,S,R;switch(e[i++]){case 0:for(x=0;x<m;x++)h[y++]=e[i++];break;case 1:for(x=0;x<m;x++)_=e[i++],S=x<a?0:h[y-a],h[y++]=(_+S)%256;break;case 2:for(x=0;x<m;x++)_=e[i++],T=(x-x%a)/a,R=f&&h[(f-1)*m+T*a+x%a],h[y++]=(R+_)%256;break;case 3:for(x=0;x<m;x++)_=e[i++],T=(x-x%a)/a,S=x<a?0:h[y-a],R=f&&h[(f-1)*m+T*a+x%a],h[y++]=(_+Math.floor((S+R)/2))%256;break;case 4:for(x=0;x<m;x++){var E,b;_=e[i++],T=(x-x%a)/a,S=x<a?0:h[y-a],0===f?R=b=0:(R=h[(f-1)*m+T*a+x%a],b=T&&h[(f-1)*m+(T-1)*a+x%a]);const t=S+R-b,r=Math.abs(t-S),n=Math.abs(t-R),s=Math.abs(t-b);E=r<=n&&r<=s?S:n<=s?R:b,h[y++]=(_+E)%256}break;default:throw new Error(`Invalid filter algorithm: ${e[i-1]}`)}if(!d){let e=((l+f*u)*t+o)*a,r=f*m;for(x=0;x<p;x++){for(let t=0;t<a;t++)n[e++]=h[r++];e+=(c-1)*a}}f++}}return 1===this.interlaceMethod?(o(0,0,8,8),o(4,0,8,8),o(0,4,4,8),o(2,0,4,4),o(0,2,2,4),o(1,0,2,2),o(0,1,1,2)):o(0,0,1,1,!0),n}decodePalette(){const{palette:e}=this,{length:t}=e,r=this.transparency.indexed||[],a=new Uint8Array((r.length||0)+t);let n=0,s=0;for(let o=0;o<t;o+=3){var i;a[n++]=e[o],a[n++]=e[o+1],a[n++]=e[o+2],a[n++]=null!=(i=r[s++])?i:255}return a}copyToImageData(e,t){let r,a,{colors:n}=this,s=null,i=this.hasAlphaChannel;this.palette.length&&(s=this._decodedPalette||(this._decodedPalette=this.decodePalette()),n=4,i=!0);const o=e.data||e,{length:l}=o,c=s||t;let u=r=0;if(1===n)for(;u<l;){a=s?4*t[u/4]:r;const e=c[a++];o[u++]=e,o[u++]=e,o[u++]=e,o[u++]=i?c[a++]:255,r=a}else for(;u<l;)a=s?4*t[u/4]:r,o[u++]=c[a++],o[u++]=c[a++],o[u++]=c[a++],o[u++]=i?c[a++]:255,r=a}decode(){const e=new Uint8Array(this.width*this.height*4);return this.copyToImageData(e,this.decodePixels()),e}renderFrame(e,t){const{frames:r}=this.animation,a=r[t],n=r[t-1];return 0===t&&e.clearRect(0,0,this.width,this.height),1===(n&&n.disposeOp)?e.clearRect(n.xOffset,n.yOffset,n.width,n.height):2===(n&&n.disposeOp)&&e.putImageData(n.imageData,n.xOffset,n.yOffset),0===a.blendOp&&e.clearRect(a.xOffset,a.yOffset,a.width,a.height),e.drawImage(a.image,a.xOffset,a.yOffset)}animate(e){let t=0;const{numFrames:r,frames:a,numPlays:n}=this.animation,s=()=>{const i=t++%r,o=a[i];this.renderFrame(e,i),r>1&&t/r<n&&(this.animation._timeout=setTimeout(s,o.delay))};s()}stopAnimation(){return clearTimeout(this.animation&&this.animation._timeout)}render(e){e._png&&e._png.stopAnimation(),e._png=this,e.width=this.width,e.height=this.height;const t=e.getContext("2d");if(this.animation)return this.decodeFrames(t),this.animate(t);{const e=t.createImageData(this.width,this.height);return this.copyToImageData(e,this.decodePixels()),t.putImageData(e,0,0)}}}return e}();function createSceneSpec(e){return{assetType:"scene",occupancyGridsSpec:createOccupancyGridsSpec(e),distanceGridsSpec:createDistanceGridsSpec(e),triplaneSpec:createTriplaneSpec(e),sparseGridSpec:createSparseGridSpec(e)}}function createOccupancyGridsSpec(e){let t=[8,16,32,64,128];return e.useBits&&(t=[8,32,128]),e.useDistanceGrid&&(t=[8]),{assetType:"occupancy_grids",gridSpecs:t.map((t=>createOccupancyGridSpec(e,"occupancy_grid",t))),blockSizes:t}}function createDistanceGridsSpec(e){if(!e.useDistanceGrid)return{assetType:"distance_grids",gridSpecs:[],blockSizes:[]};return{assetType:"distance_grids",gridSpecs:[createOccupancyGridSpec(e,"distance_grid",8)],blockSizes:[8]}}function createSparseGridSpec(e){e.export_array_format;let t=getFieldOrDefault(e,"export_store_rgb_and_density_separately",!1),r={assetType:"sparse_grid",blockIndicesSpec:createSparseGridBlockIndicesSpec(e),separateRgbAndDensity:t};return t?(r.rgbSpec=createSparseGridAssetSpec(e,"sparse_grid_rgb",3),r.densitySpec=createSparseGridAssetSpec(e,"sparse_grid_density",2),r.featuresSpec=createSparseGridAssetSpec(e,"sparse_grid_features",3)):(r.rgbAndDensitySpec=createSparseGridAssetSpec(e,"sparse_grid_rgb_and_density",4),r.featuresSpec=createSparseGridAssetSpec(e,"sparse_grid_features",4)),r}function createSparseGridBlockIndicesSpec(e){const t=e.export_array_format||"png";let r=e.sparse_grid_resolution/e.data_block_size;return{assetType:"sparse_grid_block_indices",filename:`sparse_grid_block_indices.${t}`,shape:[r,r,r],numChannels:3}}function createSparseGridAssetSpec(e,t,r){const a=e.export_array_format||"png";let n=e.num_slices,s=e.atlas_width,i=e.atlas_height,o=e.atlas_depth,l=Math.ceil(o/n),c=[];for(let e=0;e<n;++e){const o=digits(e,3);filename=`${t}_${o}.${a}`,c.push({assetType:`${t}_slice`,shape:[s,i,l],numChannels:r,sliceIndex:e,numSlices:n,filename:filename})}return{assetType:`${t}_slices`,shape:[s,i,o],numChannels:r,sliceSpecs:c,numSlices:n,mergeSlices:getMergeSlices(e)}}function createOccupancyGridSpec(e,t,r){const a=e.export_array_format||"png",n=e.triplane_resolution,s=e.triplane_voxel_size,i=Math.ceil(n/r),o=s*r;const l=getFieldOrDefault(e,"export_slice_occupancy_and_distance_grids",!0)&&i>256;let c=getFieldOrDefault(e,"export_pad_occupancy_and_distance_grids",!0)?4:1,u=[];if(e.legacyGrids||!l){let n=`${t}_${r}.${a}`;e.legacyGrids||(n=`${t}_${r}_000.${a}`),u.push({assetType:`${t}_slice`,shape:[i,i,i],numChannels:c,sliceIndex:0,numSlices:1,filename:n})}else{const e=Math.ceil(i/8);for(let n=0;n<8;++n){let s=`${t}_${r}_${digits(n,3)}.${a}`;u.push({assetType:`${t}_slice`,shape:[i,i,e],numChannels:c,sliceIndex:n,numSlices:8,filename:s})}}return{assetType:`${t}_slices`,shape:[i,i,i],numChannels:c,voxelSize:o,blockSize:r,sliceSpecs:u,numSlices:8,mergeSlices:getMergeSlices(e)}}function createTriplaneSpec(e){const t=e.triplane_resolution;let r={assetType:"triplane",shape:[t,t,3],numSlices:3,voxelSize:e.triplane_voxel_size,separateRgbAndDensity:getFieldOrDefault(e,"export_store_rgb_and_density_separately",!1),featuresSpec:createTriplaneSlicesSpec(e,"triplane_features",4)};return r.separateRgbAndDensity?(r.rgbSpec=createTriplaneSlicesSpec(e,"triplane_rgb",3),r.densitySpec=createTriplaneSlicesSpec(e,"triplane_density",1)):r.rgbAndDensitySpec=createTriplaneSlicesSpec(e,"triplane_rgb_and_density",4),r}function createTriplaneSlicesSpec(e,t,r){const a=e.triplane_resolution;return{assetType:`${t}_slices`,shape:[a,a,3],numChannels:r,numSlices:3,mergeSlices:getMergeSlices(e),sliceSpecs:range(3).map((a=>createPlaneSliceSpec(e,t,r,a)))}}function createPlaneSliceSpec(e,t,r,a){const n=e.export_array_format||"png",s=e.triplane_resolution;let i=t.replace(/^triplane_/,"plane_");return{assetType:`${t}_slice`,shape:[s,s,1],numChannels:r,sliceIndex:a,numSlices:3,filename:`${i}_${a}.${n}`}}function getMergeSlices(e){const t=getFieldOrDefault(e,"export_store_rgb_and_density_separately",!1),r=getFieldOrDefault(e,"merge_slices",!t);if(!t&&!r)throw new Error('Slices must be merged when using "rgb_and_density" images. Please re-export with export_store_rgb_and_density_separately=true and try again.');return r&&t}const baseGoogleApiUrl="https://firebasestorage.googleapis.com/v0/b/test3-2d896.appspot.com/o";let gcsToken=null;function fetchGcsToken(){return gcsToken||(gcsToken=fetch("http://localhost:3001/get-gcs-token").then((e=>{if(!e.ok)throw new Error(`Erreur lors de la récupération du jeton GCS: ${e.status}`);return e.json()})).then((e=>(gcsToken=e.token,setTimeout((()=>{gcsToken=null}),84e4),gcsToken))).catch((e=>{throw console.error("Erreur lors de la récupération du jeton GCS:",e),gcsToken=null,e})),gcsTokenPromise)}function fetchScene(e,t){return{...e,occupancyGridsAsset:fetchAsset(e.occupancyGridsSpec,t),distanceGridsAsset:fetchAsset(e.distanceGridsSpec,t),triplaneAsset:fetchAsset(e.triplaneSpec,t),sparseGridAsset:fetchAsset(e.sparseGridSpec,t)}}function fetchOccupancyGrids(e,t){let r=e.gridSpecs.map((e=>fetchAsset(e,t)));return{...e,gridAssets:r}}function fetchSlices(e,t){let r=e.sliceSpecs.map((e=>fetchAsset(e,t)));return{...e,sliceAssets:r}}function fetchTriplane(e,t){let r={...e,featuresAsset:fetchAsset(e.featuresSpec,t)};return e.separateRgbAndDensity?(r.rgbAsset=fetchAsset(e.rgbSpec,t),r.densityAsset=fetchAsset(e.densitySpec,t)):r.rgbAndDensityAsset=fetchAsset(e.rgbAndDensitySpec,t),r}function fetchArray(e,t){const r=t.dirUrl;if("string"!=typeof r)throw console.error("dirUrl is not a valid string:",r),new Error("dirUrl must be a valid string");if(!e.filename)throw console.error("Spec missing filename:",e),new Error("Spec must contain a valid filename");const a=cleanPath(r),n=e.filename.endsWith(".gz")?e.filename.slice(0,-3):e.filename,s=encodeURIComponent(a),i=`${baseGoogleApiUrl}/users%2Fvisite_3D%2F${s}%2F${n}?alt=media&token=${gcsToken}`;console.log("Fetching from URL:",i);const o=loadAsset(i).then(validateSize(e)).then(onImageLoaded);return{...e,asset:o}}function validateSize(e){return t=>{const r=product(e.shape)*e.numChannels;return console.assert(t.length===r,`Size mismatch for ${e.filename}`,e,t),t}}function cleanPath(e){const t=e.split("/"),r=[];for(let e=0;e<t.length;e++)".."===t[e]?r.length&&r.pop():"."!==t[e]&&""!==t[e]&&r.push(t[e]);return r.join("/")}function fetchSparseGrid(e,t){let r={...e,blockIndicesAsset:fetchAsset(e.blockIndicesSpec,t),featuresAsset:fetchAsset(e.featuresSpec,t)};return e.separateRgbAndDensity?(r.rgbAsset=fetchAsset(e.rgbSpec,t),r.densityAsset=fetchAsset(e.densitySpec,t)):r.rgbAndDensityAsset=fetchAsset(e.rgbAndDensitySpec,t),r}function notImplementedError(e,t){console.error(`${e.assetType} is not yet implemented`,e)}const gFetchRegistry={scene:fetchScene,triplane:fetchTriplane,triplane_rgb_and_density_slices:fetchSlices,triplane_rgb_and_density_slice:fetchArray,triplane_rgb_slices:fetchSlices,triplane_rgb_slice:fetchArray,triplane_density_slices:fetchSlices,triplane_density_slice:fetchArray,triplane_features_slices:fetchSlices,triplane_features_slice:fetchArray,distance_grids:fetchOccupancyGrids,distance_grid_slices:fetchSlices,distance_grid_slice:fetchArray,occupancy_grids:fetchOccupancyGrids,occupancy_grid_slices:fetchSlices,occupancy_grid_slice:fetchArray,sparse_grid:fetchSparseGrid,sparse_grid_block_indices:fetchArray,sparse_grid_rgb_and_density_slices:fetchSlices,sparse_grid_rgb_and_density_slice:fetchArray,sparse_grid_rgb_slices:fetchSlices,sparse_grid_rgb_slice:fetchArray,sparse_grid_density_slices:fetchSlices,sparse_grid_density_slice:fetchArray,sparse_grid_features_slices:fetchSlices,sparse_grid_features_slice:fetchArray};function fetchAsset(e,t){let r=gFetchRegistry[e.assetType];return null==r&&console.error(`Failed to find fetchFn for assetType ${e.assetType}`,e),r(e,t)}function createEmptyVolumeTexture(e,t,r,a,n){let s=new THREE.DataTexture3D(null,e,t,r);return s.internalFormat=getInternalFormat(a),s.format=a,s.generateMipmaps=!1,s.magFilter=s.minFilter=n,s.wrapS=s.wrapT=s.wrapR=THREE.ClampToEdgeWrapping,s.type=THREE.UnsignedByteType,s.unpackAlignment=1,gRenderer.initTexture(s),s}function createEmptyTriplaneTextureArray(e,t,r,a){let n=new THREE.DataTexture2DArray(null,e,t,r);return n.internalFormat=getInternalFormat(a),n.format=a,n.generateMipmaps=!1,n.magFilter=n.minFilter=THREE.LinearFilter,n.wrapS=n.wrapT=n.wrapR=THREE.ClampToEdgeWrapping,n.type=THREE.UnsignedByteType,n.unpackAlignment=1,gRenderer.initTexture(n),n}function getInternalFormat(e){if(e==THREE.RedFormat)return"R8";if(e==THREE.LuminanceAlphaFormat)return"LUMINANCE_ALPHA";if(e==THREE.RGBFormat)return"RGB";if(e==THREE.RGBAFormat)return"RGBA";throw new Error(`Unrecognized THREE.js format: ${e}`)}function createEmptySceneTexture(e){return{textureType:"scene",occupancyGridsTexture:createEmptyTexture(e.occupancyGridsSpec),distanceGridsTexture:createEmptyTexture(e.distanceGridsSpec),triplaneTexture:createEmptyTexture(e.triplaneSpec),sparseGridTexture:createEmptyTexture(e.sparseGridSpec)}}function createEmptyOccupancyGridsTexture(e){return{textureType:e.assetType.replace(/_slices$/,""),gridTextures:e.gridSpecs.map(createEmptyTexture)}}function createEmptyOccupancyGridTexture(e){return{textureType:e.assetType.replace(/_slices$/,""),texture:createEmptyVolumeTexture(...e.shape,THREE.RedFormat,THREE.NearestFilter)}}function createEmptyTriplaneTexture(e){let t={textureType:"triplane",featuresTexture:createEmptyTexture(e.featuresSpec)};if(e.separateRgbAndDensity)t.rgbTexture=createEmptyTexture(e.rgbSpec),t.densityTexture=createEmptyTexture(e.densitySpec);else{let r=e.rgbAndDensitySpec.shape;t.rgbTexture=createEmptyTexture({assetType:"triplane_rgb_slices",shape:r}),t.densityTexture=createEmptyTexture({assetType:"triplane_density_slices",shape:r})}return t}function createEmptyTriplaneSlicesTexture(e){let t=e.assetType.replace(/_slices$/,""),r={triplane_density:THREE.RedFormat,triplane_rgb:THREE.RGBFormat,triplane_features:THREE.RGBAFormat}[t];return console.assert(null!=r,e),{textureType:t,texture:createEmptyTriplaneTextureArray(...e.shape,r)}}function createEmptySparseGridTexture(e){let t=(e,t)=>createEmptyVolumeTexture(...e.shape,t,THREE.LinearFilter),r=e.separateRgbAndDensity?e.rgbSpec:e.rgbAndDensitySpec,a=e.separateRgbAndDensity?e.densitySpec:e.rgbAndDensitySpec,n=t(r,THREE.RGBFormat),s=t(a,THREE.LuminanceAlphaFormat),i=t(e.featuresSpec,THREE.RGBFormat);return{textureType:"sparse_grid",blockIndicesTexture:{textureType:"sparse_grid_block_indices",texture:createEmptyVolumeTexture(...e.blockIndicesSpec.shape,THREE.RGBFormat,THREE.NearestFilter)},rgbTexture:{textureType:"sparse_grid_rgb",texture:n},densityTexture:{textureType:"sparse_grid_density",texture:s},featuresTexture:{textureType:"sparse_grid_features",texture:i}}}const gCreateEmptyTextureRegistry={scene:createEmptySceneTexture,triplane:createEmptyTriplaneTexture,triplane_rgb_slices:createEmptyTriplaneSlicesTexture,triplane_density_slices:createEmptyTriplaneSlicesTexture,triplane_features_slices:createEmptyTriplaneSlicesTexture,distance_grids:createEmptyOccupancyGridsTexture,distance_grid_slices:createEmptyOccupancyGridTexture,occupancy_grids:createEmptyOccupancyGridsTexture,occupancy_grid_slices:createEmptyOccupancyGridTexture,sparse_grid:createEmptySparseGridTexture};function createEmptyTexture(e){let t=gCreateEmptyTextureRegistry[e.assetType];return null==t&&console.error(`Failed to find loadFn for assetType ${e.assetType}`,e),t(e)}function prepareScenePayload(e){return{textureType:"scene",occupancyGridsPayload:prepareTexturePayload(e.occupancyGridsAsset),distanceGridsPayload:prepareTexturePayload(e.distanceGridsAsset),triplanePayload:prepareTexturePayload(e.triplaneAsset),sparseGridPayload:prepareTexturePayload(e.sparseGridAsset)}}function prepareOccupancyGridsPayload(e){return{textureType:e.assetType,gridPayloads:e.gridAssets.map(prepareTexturePayload)}}function prepareOccupancyGridPayload(e){return e.mergeSlices?prepareOccupancyGridMergedPayload(e):prepareOccupancyGridSlicesPayload(e)}function prepareOccupancyGridMergedPayload(e){return console.assert(e.assetType.endsWith("_slices"),e),{textureType:e.assetType.replace(/_slices$/,""),shape:e.shape,numChannels:e.numChannels,payload:mergeSlices(e,{1:GridTextureSource.RED_FROM_RED,4:GridTextureSource.ALPHA_FROM_RGBA}[e.numChannels],GridTextureDestination.RED_IN_RED)}}function prepareOccupancyGridSlicesPayload(e){return console.assert(e.assetType.endsWith("_slices"),e),{textureType:e.assetType.replace(/_slices$/,""),shape:e.shape,numChannels:e.numChannels,slicePayloads:e.sliceAssets.map(prepareTexturePayload)}}function prepareOccupancyGridSlicePayload(e){console.assert(e.assetType.endsWith("_slice"),e);let t=null;if(1==e.numChannels)t=e.asset;else{if(4!=e.numChannels)throw new Error("Unrecognized number of input channels",e);t=mergeSlices({shape:e.shape,numSlices:1,sliceAssets:[{...e,sliceIndex:0,numSlices:1}]},GridTextureSource.ALPHA_FROM_RGBA,GridTextureDestination.RED_IN_RED)}return{textureType:e.assetType,shape:e.shape,numChannels:e.numChannels,sliceIndex:e.sliceIndex,numSlices:e.numSlices,payload:t}}function prepareTriplanePayload(e){let t={textureType:"triplane",featuresPayload:preparePlanePayload(e.featuresAsset,"triplane_features",GridTextureSource.RGBA_FROM_RGBA,GridTextureDestination.RGBA_IN_RGBA)};return e.separateRgbAndDensity?(t.rgbPayload=preparePlanePayload(e.rgbAsset,"triplane_rgb",GridTextureSource.RGB_FROM_RGB,GridTextureDestination.RGB_IN_RGB),t.densityPayload=preparePlanePayload(e.densityAsset,"triplane_density",GridTextureSource.RED_FROM_RED,GridTextureDestination.RED_IN_RED)):(t.rgbPayload=preparePlanePayload(e.rgbAndDensityAsset,"triplane_rgb",GridTextureSource.RGB_FROM_RGBA,GridTextureDestination.RGB_IN_RGB),t.densityPayload=preparePlanePayload(e.rgbAndDensityAsset,"triplane_density",GridTextureSource.ALPHA_FROM_RGBA,GridTextureDestination.RED_IN_RED)),t}function preparePlanePayload(e,t,r,a){let n={textureType:t,shape:e.shape,numChannels:e.numChannels};return e.mergeSlices?n.payload=mergeSlices(e,r,a):n.slicePayloads=e.sliceAssets.map((e=>preparePlaneSlicePayload(e,r,a))),n}function preparePlaneSlicePayload(e,t,r){let a=null;return a=t.format==r.format&&t.channels==r.channels?e.asset:mergeSlices({shape:e.shape,numSlices:1,sliceAssets:[{...e,sliceIndex:0,numSlices:1}]},t,r),{textureType:e.assetType,shape:e.shape,sliceIndex:e.sliceIndex,numSlices:e.numSlices,numChannels:e.numChannels,payload:a}}function prepareArrayPayload(e){return{textureType:e.assetType,payload:e.asset,shape:e.shape,numChannels:e.numChannels}}function prepareSparseGridPayload(e){let t={textureType:"sparse_grid",blockIndicesPayload:prepareTexturePayload(e.blockIndicesAsset),featuresPayload:prepareTexturePayload(e.featuresAsset)};return e.separateRgbAndDensity?(t.rgbPayload=prepareTexturePayload(e.rgbAsset),t.densityPayload=prepareTexturePayload(e.densityAsset)):(t.rgbPayload=prepareTexturePayload(e.rgbAndDensityAsset),t.densityPayload=prepareSparseGridDensityPayload(e)),t}function prepareSparseGridGenericPayload(e){return e.mergeSlices?prepareSparseGridGenericMergedPayload(e):prepareSparseGridGenericSlicesPayload(e)}function prepareSparseGridGenericMergedPayload(e){let t=e.assetType.replace(/_slices$/,"");t.includes("rgb_and_density")&&(t=t.replace(/rgb_and_density$/,"rgb"));let r={2:GridTextureSource.LA_FROM_LUMINANCE_ALPHA,3:GridTextureSource.RGB_FROM_RGB,4:GridTextureSource.RGB_FROM_RGBA},a={2:GridTextureDestination.LA_IN_LUMINANCE_ALPHA,3:GridTextureDestination.RGB_IN_RGB,4:GridTextureDestination.RGB_IN_RGB},n=mergeSlices(e,r[e.numChannels],a[e.numChannels]);return{textureType:t,shape:e.shape,numChannels:e.numChannels,payload:n}}function prepareSparseGridGenericSlicesPayload(e){let t=e.assetType.replace(/_slices$/,"");return t.includes("rgb_and_density")&&(t=t.replace(/rgb_and_density$/,"rgb")),{textureType:t,shape:e.shape,numChannels:e.numChannels,numSlices:e.numSlices,slicePayloads:e.sliceAssets.map(prepareTexturePayload)}}function prepareSparseGridGenericSlicePayload(e){let t=e.assetType,r=null;if("sparse_grid_rgb_slice"==t&&3==e.numChannels||"sparse_grid_density_slice"==t&&2==e.numChannels||"sparse_grid_features_slice"==t&&3==e.numChannels)r=e.asset;else{let t={2:GridTextureSource.LA_FROM_LUMINANCE_ALPHA,3:GridTextureSource.RGB_FROM_RGB,4:GridTextureSource.RGB_FROM_RGBA},a={2:GridTextureDestination.LA_IN_LUMINANCE_ALPHA,3:GridTextureDestination.RGB_IN_RGB,4:GridTextureDestination.RGB_IN_RGB};r=mergeSlices({shape:e.shape,numSlices:1,sliceAssets:[{...e,sliceIndex:0,numSlices:1}]},t[e.numChannels],a[e.numChannels])}let a=t;return a.includes("rgb_and_density")&&(a=a.replace(/_rgb_and_density$/,"rgb")),{textureType:a,shape:e.shape,numChannels:e.numChannels,sliceIndex:e.sliceIndex,numSlices:e.numSlices,payload:r}}function prepareSparseGridDensityPayload(e){return{textureType:"sparse_grid_density",shape:e.rgbAndDensityAsset.shape,numChannels:2,payload:mergeSparseGridDensity(e)}}const gPrepareTexturePayloadRegistry={scene:prepareScenePayload,triplane:prepareTriplanePayload,distance_grids:prepareOccupancyGridsPayload,distance_grid_slices:prepareOccupancyGridPayload,distance_grid_slice:prepareOccupancyGridSlicePayload,occupancy_grids:prepareOccupancyGridsPayload,occupancy_grid_slices:prepareOccupancyGridPayload,occupancy_grid_slice:prepareOccupancyGridSlicePayload,sparse_grid:prepareSparseGridPayload,sparse_grid_block_indices:prepareArrayPayload,sparse_grid_rgb_and_density_slices:prepareSparseGridGenericPayload,sparse_grid_rgb_and_density_slice:prepareSparseGridGenericSlicePayload,sparse_grid_rgb_slices:prepareSparseGridGenericPayload,sparse_grid_rgb_slice:prepareSparseGridGenericSlicePayload,sparse_grid_density_slices:prepareSparseGridGenericPayload,sparse_grid_density_slice:prepareSparseGridGenericSlicePayload,sparse_grid_features_slices:prepareSparseGridGenericPayload,sparse_grid_features_slice:prepareSparseGridGenericSlicePayload};function prepareTexturePayload(e){let t=gPrepareTexturePayloadRegistry[e.assetType];return null==t&&console.error(`Failed to find loadFn for assetType ${e.assetType}`,e),t(e)}function populateScene(e,t){let r=[populateTexture(e.occupancyGridsTexture,t.occupancyGridsPayload),populateTexture(e.distanceGridsTexture,t.distanceGridsPayload),populateTexture(e.triplaneTexture,t.triplanePayload),populateTexture(e.sparseGridTexture,t.sparseGridPayload)];return Promise.all(r)}function populateOccupancyGridsTexture(e,t){console.assert(e.gridTextures.length==t.gridPayloads.length,e,t);let r=range(e.gridTextures.length).map((r=>populateTexture(e.gridTextures[r],t.gridPayloads[r])));return Promise.all(r)}function populateSparseGridTexture(e,t){let r=[populateTexture(e.blockIndicesTexture,t.blockIndicesPayload),populateTexture(e.rgbTexture,t.rgbPayload),populateTexture(e.densityTexture,t.densityPayload),populateTexture(e.featuresTexture,t.featuresPayload)];return Promise.all(r)}function populateTriplaneTexture(e,t){return Promise.all([populateTexture(e.rgbTexture,t.rgbPayload),populateTexture(e.densityTexture,t.densityPayload),populateTexture(e.featuresTexture,t.featuresPayload)])}async function populateArrayTexture(e,t){if(null==t.payload)throw new Error("Unclear how to ingest payload",e,t);e.texture.image.data=await t.payload,e.texture.needsUpdate=!0}function populateArrayTextureWithWebGL(e,t){if(null!=t.payload)return populateArrayTextureMergedWithWebGL(e,t);if(null!=t.slicePayloads){let r=t.slicePayloads.map((t=>populateArrayTextureSliceWithWebGL(e,t)));return Promise.all(r)}throw new Error("Unclear how to ingest payload",e,t)}async function populateArrayTextureSliceWithWebGL(e,t){let r=gRenderer.getContext();const a=t.shape[0],n=t.shape[1],s=t.shape[2],i=t.sliceIndex;let o=e.texture.format,{glFormat:l,glInternalFormat:c,numChannels:u}=threeFormatToOpenGLFormat(r,o),d=await t.payload;let p,g,m=gRenderer.properties.get(e.texture).__webglTexture;console.assert(null!=m,e),e.texture instanceof THREE.DataTexture3D?(p=r.TEXTURE_BINDING_3D,g=r.TEXTURE_3D):e.texture instanceof THREE.DataTexture2DArray&&(p=r.TEXTURE_BINDING_2D_ARRAY,g=r.TEXTURE_2D_ARRAY);let h=r.getParameter(p);r.bindTexture(g,m);performance.mark(`${e.textureType}-start`);r.texSubImage3D(g,0,0,0,i*s,a,n,s,l,r.UNSIGNED_BYTE,d,0);performance.mark(`${e.textureType}-end`);performance.measure(`${e.textureType}-duration`,`${e.textureType}-start`,`${e.textureType}-end`),r.bindTexture(g,h)}async function populateArrayTextureMergedWithWebGL(e,t){return populateArrayTextureSliceWithWebGL(e,{...t,sliceIndex:0,numSlices:1})}function threeFormatToOpenGLFormat(e,t){if(t==THREE.RGBAFormat)return{numChannels:4,glFormat:e.RGBA,glInternalFormat:e.RGBA};if(t==THREE.RGBFormat)return{numChannels:3,glFormat:e.RGB,glInternalFormat:e.RGB};if(t==THREE.LuminanceAlphaFormat)return{numChannels:2,glFormat:e.LUMINANCE_ALPHA,glInternalFormat:e.LUMINANCE_ALPHA};if(t==THREE.RedFormat)return{numChannels:1,glFormat:e.RED,glInternalFormat:e.R8};throw new Error(`Unrecognized three format: ${t}`)}const gPopulateTextureRegistry={scene:populateScene,triplane:populateTriplaneTexture,triplane_rgb:populateArrayTextureWithWebGL,triplane_density:populateArrayTextureWithWebGL,triplane_features:populateArrayTextureWithWebGL,distance_grids:populateOccupancyGridsTexture,distance_grid:populateArrayTextureWithWebGL,occupancy_grids:populateOccupancyGridsTexture,occupancy_grid:populateArrayTextureWithWebGL,sparse_grid:populateSparseGridTexture,sparse_grid_block_indices:populateArrayTextureWithWebGL,sparse_grid_rgb:populateArrayTextureWithWebGL,sparse_grid_density:populateArrayTextureWithWebGL,sparse_grid_features:populateArrayTextureWithWebGL};function populateTexture(e,t){let r=gPopulateTextureRegistry[e.textureType];return null==r&&console.error(`Failed to find loadFn for assetType ${e.textureType}`,e),r(e,t)}const NEEDS_NEW_SUBMODEL=-1,LOADING=0,READY=1;let gSubmodelSceneContents={},gSubmodelCacheSize=10,gRayMarchTextureBuffers=[{si:0,state:-1,texture:null},{si:0,state:-1,texture:null}],gActiveRayMarchTextureBuffer=0,gRayMarchScene=null;function getRayMarchScene(){if(null==gRayMarchScene)throw new Error("gRayMarchScene has not been initialized yet!");return gRayMarchScene}function getActiveSubmodelIndex(){return gRayMarchTextureBuffers[gActiveRayMarchTextureBuffer].si}function getActiveSubmodelContent(){return getSubmodelContent(getActiveSubmodelIndex())}function getSubmodelScale(e){return getSubmodelContent(e).params.submodel_scale}function getSubmodelScaleFactor(e){let t=getSubmodelContent(e);return getSubmodelScale(e)/Math.cbrt(t.params.num_submodels)}function getSubmodelContent(e){return gSubmodelSceneContents[e]}function registerSubmodelContent(e,t){gSubmodelSceneContents[e]=t}function getDeferredMlp(){return console.assert(null!=gDeferredMlp),gDeferredMlp}function registerDeferredMlp(e){validateDeferredMlp(e),gDeferredMlp=e}function getCurrentTextureUsageInBytes(){let e=0;for(rmtb of gRayMarchTextureBuffers)e+=getTextureSizeInBytes(rmtb.texture);return e}function setCurrentRayMarchScene(e){let t=gActiveRayMarchTextureBuffer,r=gRayMarchTextureBuffers[t],a=(t+1)%2,n=gRayMarchTextureBuffers[a];if(null==getSubmodelContent(e))return Promise.resolve();if(getSubmodelContent(e).lastTouched=Date.now(),e==r.si&&r.state>=0)return Promise.resolve();if(e==n.si&&1==n.state){return console.log(`Switching to buffer ${a} for submodel #${e}`),setTextureUniforms(getSubmodelContent(e).params,n.texture),gActiveRayMarchTextureBuffer=a,Promise.resolve()}return n.state>=0&&n.state<1?Promise.resolve():(console.log(`Preparing texture buffer #${a} for submodel #${e}`),n.si=e,n.state=0,Promise.resolve().then((()=>{reinitializeSparseGridTextures(n);let e=getSubmodelContent(n.si);if(null==e.payload){console.log(`Fetching assets for submodel #${n.si}`);let t=prepareTexturePayload(fetchAsset(e.spec,e.router));e.payload=t}return console.log(`Populating textures for submodel #${n.si} into buffer #${a}`),populateTexture(n.texture,e.payload)})).then((()=>{n.state=1,console.log(`Submodel #${n.si} is ready for rendering`),hideLoading()})))}function garbageCollectSubmodelPayloads(){let e=[];for(let t of Object.keys(gSubmodelSceneContents)){let r=getSubmodelContent(t);null!=r.payload&&e.push({lastTouched:r.lastTouched||0,si:t})}e.sort(((e,t)=>e.lastTouched-t.lastTouched));for(let t=0;t<e.length-gSubmodelCacheSize;++t){let r=e[t].si;console.log(`Deleting payload for submodel #${r}`),getSubmodelContent(r).payload=null}}function initializeSceneContent(e,t){return{spec:createSceneSpec(e),params:e,router:t,payload:null}}function reinitializeSparseGridTextures(e){let t=e.texture.sparseGridTexture;t.blockIndicesTexture.texture.dispose(),t.rgbTexture.texture.dispose(),t.densityTexture.texture.dispose(),t.featuresTexture.texture.dispose();let r=getSubmodelContent(e.si).spec.sparseGridSpec;e.texture.sparseGridTexture=createEmptyTexture(r)}async function initializePingPongBuffers(e){let t=getSubmodelContent(e);gRayMarchScene=await initializeRayMarchScene(e,t);for(let e of gRayMarchTextureBuffers)e.texture=createEmptyTexture(t.spec);setTextureUniforms(t.params,gRayMarchTextureBuffers[0].texture),gActiveRayMarchTextureBuffer=0}async function initializeDeferredMlp(e){let t=getSubmodelContent(e),r=t.params;if(r.export_store_deferred_mlp_separately){return loadJSONFile(t.router.translate("deferred_mlp.json")).then(registerDeferredMlp)}return registerDeferredMlp(r.deferred_mlp)}function setTextureUniforms(e,t){let r=getRayMarchScene().children[0].material.uniforms,a=t.occupancyGridsTexture.gridTextures,n=a.length;for(let e=0;e<n;++e){let t=a[e];r["occupancyGrid_L"+(n-e-1)].value=t.texture}if(e.useDistanceGrid){let e=t.distanceGridsTexture.gridTextures[0].texture;r.distanceGrid.value=e}let s=t.triplaneTexture;r.planeDensity.value=s.densityTexture.texture,r.planeRgb.value=s.rgbTexture.texture,r.planeFeatures.value=s.featuresTexture.texture;let i=t.sparseGridTexture;r.sparseGridBlockIndices.value=i.blockIndicesTexture.texture,r.sparseGridDensity.value=i.densityTexture.texture,r.sparseGridRgb.value=i.rgbTexture.texture,r.sparseGridFeatures.value=i.featuresTexture.texture,r.atlasSize.value=new THREE.Vector3(e.atlas_width,e.atlas_height,e.atlas_depth)}function getTextureSizeInBytes(e){let t=0,r=e=>{if(null==e)return 0;let t=e.texture.image;return t.height*t.width*t.depth},a=e.occupancyGridsTexture.gridTextures,n=a.length;for(let e=0;e<n;++e){t+=1*r(a[e])}if(e.distanceGridsTexture.gridTextures.length>0){t+=1*r(e.distanceGridsTexture.gridTextures[0])}let s=e.triplaneTexture;t+=3*r(s.rgbTexture),t+=1*r(s.densityTexture),t+=4*r(s.featuresTexture);let i=e.sparseGridTexture;return t+=1*r(i.blockIndicesTexture),t+=3*r(i.rgbTexture),t+=1*r(i.densityTexture),t+=4*r(i.featuresTexture),t}async function initializeRayMarchScene(e,t){let r=t.params,a=t.spec,n=kRayMarchFragmentShaderHeader;n+=await loadTextFile("viewdependency.glsl"),n+=await loadTextFile("fragment.glsl"),n=rewriteViewDependenceDefinitions(r,n);let s=new THREE.Matrix3;s.set(-1,0,0,0,0,1,0,1,0);let i=new THREE.Vector3(-2,-2,-2);n="#define kMinPosition vec3("+Number(i.x).toFixed(10)+", "+Number(i.y).toFixed(10)+", "+Number(i.z).toFixed(10)+")\n"+n,n="#define kSubmodelScale "+Number(getSubmodelScale(e)).toFixed(10)+"\n"+n,n="#define kStepMult "+gStepMult+"\n"+n,n="#define kRangeFeaturesMin "+Number(r.range_features[0]).toFixed(10)+"\n"+n,n="#define kRangeFeaturesMax "+Number(r.range_features[1]).toFixed(10)+"\n"+n,n="#define kRangeDensityMin "+Number(r.range_density[0]).toFixed(10)+"\n"+n,n="#define kRangeDensityMax "+Number(r.range_density[1]).toFixed(10)+"\n"+n;let o={bias_0:{value:null},bias_1:{value:null},bias_2:{value:null},weightsZero:{value:null},weightsOne:{value:null},weightsTwo:{value:null},displayMode:{value:gDisplayMode-0},minPosition:{value:i},world_T_cam:{value:new THREE.Matrix4},cam_T_clip:{value:new THREE.Matrix4},worldspaceROpengl:{value:s}};occupancyUniforms={};let l=a.occupancyGridsSpec.gridSpecs,c=l.length;for(let e=0;e<c;++e){let t=l[e],r=c-e-1;n="#define kVoxelSizeOccupancy_L"+r+" "+Number(t.voxelSize).toFixed(10)+"\n"+n,n="#define kGridSizeOccupancy_L"+r+" vec3("+Number(t.shape[0]).toFixed(10)+", "+Number(t.shape[1]).toFixed(10)+", "+Number(t.shape[2]).toFixed(10)+")\n"+n,occupancyUniforms["occupancyGrid_L"+r]={value:null}}if(o=extend(o,occupancyUniforms),r.useDistanceGrid){let e=a.distanceGridsSpec.gridSpecs[0];n="#define USE_DISTANCE_GRID\n"+n,n="#define kVoxelSizeDistance "+Number(e.voxelSize).toFixed(10)+"\n"+n,n="#define kGridSizeDistance vec3("+Number(e.shape[0]).toFixed(10)+", "+Number(e.shape[1]).toFixed(10)+", "+Number(e.shape[2]).toFixed(10)+")\n"+n,distanceUniforms={distanceGrid:{value:null}},o=extend(o,distanceUniforms)}let u=new THREE.Color(.5,.5,.5);r.backgroundColor&&(u=new THREE.Color(r.backgroundColor)),n="#define kBackgroundColor vec3("+Number(u.r).toFixed(10)+", "+Number(u.g).toFixed(10)+", "+Number(u.b).toFixed(10)+")\n"+n,(gExposure||r.default_exposure)&&(r.default_exposure&&(gExposure=parseFloat(r.default_exposure)),n="#define USE_EXPOSURE\n"+n,exposureUniforms={exposure:{value:gExposure}},o=extend(o,exposureUniforms));n="#define ACTIVATION_FN "+(r.activation?r.activation:"elu")+"\n"+n,null!==r.feature_gating&&void 0!==r.feature_gating&&!0!==r.feature_gating||(n="#define USE_FEATURE_GATING\n"+n),"vfr"===r.deferred_rendering_mode&&(n="#define USE_VFR\n"+n),"coarse_sum"===r.merge_features_combine_op&&(n="#define USE_FEATURE_CONCAT\n"+n),r.useBits&&(n="#define USE_BITS\n"+n),r.useLargerStepsWhenOccluded&&(n="#define LARGER_STEPS_WHEN_OCCLUDED\n"+n,n="#define kVisibilityDelay "+Number(r.step_size_visibility_delay).toFixed(10)+"\n"+n);let d=new THREE.Vector2(...a.triplaneSpec.shape);n="#define kTriplaneVoxelSize "+Number(r.triplane_voxel_size).toFixed(10)+"\n"+n,n="#define kTriplaneGridSize vec2("+Number(d.x).toFixed(10)+", "+Number(d.y).toFixed(10)+")\n"+n;o=extend(o,{planeDensity:{value:null},planeRgb:{value:null},planeFeatures:{value:null}}),n="#define kDataBlockSize "+Number(r.data_block_size).toFixed(10)+"\n"+n,n="#define kSparseGridVoxelSize "+Number(r.sparse_grid_voxel_size).toFixed(10)+"\n"+n,n="#define kSparseGridGridSize vec3("+Number(r.sparse_grid_resolution).toFixed(10)+", "+Number(r.sparse_grid_resolution).toFixed(10)+", "+Number(r.sparse_grid_resolution).toFixed(10)+")\n"+n;o=extend(o,{sparseGridBlockIndices:{value:null},sparseGridDensity:{value:null},sparseGridRgb:{value:null},sparseGridFeatures:{value:null},atlasSize:{value:null}});let p=new THREE.ShaderMaterial({uniforms:o,vertexShader:kRayMarchVertexShader,fragmentShader:n,vertexColors:!0});p.side=THREE.DoubleSide,p.depthTest=!1,p.needsUpdate=!0;const g=new THREE.PlaneBufferGeometry(...gViewportDims);let m=new THREE.Mesh(g,p);m.position.z=-100,m.frustumCulled=!1;let h=new THREE.Scene;return h.add(m),h.autoUpdate=!1,h}function validateDeferredMlp(e){const t=e["ResampleDense_0/kernel"]?"ResampleDense":"Dense";for(let r=0;r<3;r++){const a=`${t}_${r}`;let n=e[`${a}/kernel`].shape,s=e[`${a}/bias`].shape;if("ResampleDense"===t){let e=n[1];console.assert(e===n[2]&&e===n[3]),console.assert(n[0]===s[0]&&n[1]===s[1]&&n[2]===s[2]&&n[3]===s[3])}}}class WorkerPool{constructor(e,t){let r=this;e=e||2,this.workers=[];for(let a=0;a<e;++a){let e=new Worker(t);e.onmessage=e=>{r.onmessage(e)},this.workers.push(e)}this.nextworker=0,this.callbacks={},this.i=0}submit(e,t){const r=this.i;this.callbacks[r]=t,this.i+=1;const a=this.nextworker,n=this.workers[a];this.nextworker=(a+1)%this.workers.length,n.postMessage({i:r,request:e})}onmessage(e){const t=e.data,r=t.i;(0,this.callbacks[r])(t.result),delete this.callbacks[r]}}let gStats=null,gUseSubmodel=!1,gSubmodelTransform=null,gDeferredMlp=null;const DisplayModeType={DISPLAY_NORMAL:0,DISPLAY_DIFFUSE:1,DISPLAY_FEATURES:2,DISPLAY_VIEW_DEPENDENT:3,DISPLAY_COARSE_GRID:4};let gDisplayMode=DisplayModeType.DISPLAY_NORMAL,gBenchmark=!1,gFrameMult=1,gLoadAssetsWorker=new WorkerPool(4,"loadpng.worker.js"),gCopySliceWorker=new WorkerPool(4,"copyslices.worker.js");const kRayMarchVertexShader="\nvarying vec3 vOrigin;\nvarying vec3 vDirection;\nuniform mat4 world_T_cam;\nuniform mat4 cam_T_clip;\n\nvoid main() {\n vec4 posClip = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n gl_Position = posClip;\n posClip /= posClip.w;\n\n vec4 originCam = vec4(0.0, 0.0, 0.0, 1.0);\n vec4 nearPointCam = cam_T_clip * vec4(posClip.x, posClip.y, -1.0, 1.0);\n nearPointCam /= -nearPointCam.z;\n\n vec4 originWorld = world_T_cam * originCam;\n vec4 nearPointWorld = world_T_cam * nearPointCam;\n vOrigin = originWorld.xyz / originWorld.w;\n vDirection = nearPointWorld.xyz / nearPointWorld.w - vOrigin;\n}\n",kRayMarchFragmentShaderHeader="\nprecision highp float;\n\nvarying vec3 vOrigin;\nvarying vec3 vDirection;\n\nuniform int displayMode;\n\nuniform mat3 worldspaceROpengl;\nuniform float nearPlane;\n\n#ifdef USE_DISTANCE_GRID\nuniform highp sampler3D distanceGrid;\nuniform highp sampler3D occupancyGrid_L0;\n#else\nuniform highp sampler3D occupancyGrid_L0;\nuniform highp sampler3D occupancyGrid_L1;\nuniform highp sampler3D occupancyGrid_L2;\n#ifndef USE_BITS\nuniform highp sampler3D occupancyGrid_L3;\nuniform highp sampler3D occupancyGrid_L4;\n#endif\n#endif\n\nuniform vec4 bias_0[NUM_CHANNELS_ONE/4];\nuniform vec4 bias_1[NUM_CHANNELS_TWO/4];\nuniform vec4 bias_2[NUM_CHANNELS_THREE/4];\n\nuniform highp sampler2D weightsZero;\nuniform highp sampler2D weightsOne;\nuniform highp sampler2D weightsTwo;\n\n#ifdef USE_EXPOSURE\nuniform float exposure;\n#endif\n\nuniform vec3 atlasSize;\n\nuniform highp sampler3D sparseGridBlockIndices;\nuniform highp sampler3D sparseGridDensity;\nuniform highp sampler3D sparseGridRgb;\nuniform highp sampler3D sparseGridFeatures;\n\n// need to use texture arrays, otherwise we exceed max texture unit limit\nuniform highp sampler2DArray planeDensity;\nuniform highp sampler2DArray planeRgb;\nuniform highp sampler2DArray planeFeatures;\n";let gRenderer=null,gSubmodelCount=1,gCamera=null,gViewportDims=[640,480],gNumTextures=0,gLoadedTextures=0,gSubmodelForceIndex=-1;function extend(e,t){for(let r in t)t.hasOwnProperty(r)&&(e[r]=t[r]);return e}function error(e){const t=document.getElementById("error");t.textContent=e,t.style.display="block"}function create(e,t){const r=document.createElement(e);return t&&(r.className=t),r}function digits(e,t){const r=""+e;return r.length>=t?r:("00000"+r).substr(-t)}function setupViewport(e,t){gViewportDims=[e,t]}function range(e){return[...Array(e).keys()]}function product(e){result=1;for(let t of e)result*=t;return result}function sum(e){result=1;for(let t of e)result+=t;return result}function setDims(e,t,r){e.style.width=t.toFixed(2)+"px",e.style.height=r.toFixed(2)+"px"}function hideLoading(){document.getElementById("Loading").style.display="none",document.getElementById("loading-container").style.display="none"}function showLoading(){document.getElementById("Loading").style.display="none",document.getElementById("loading-container").style.display="none"}function isLoading(){return"none"!==document.getElementById("Loading").style.display}function onImageFetch(e){return gNumTextures++,updateLoadingProgress(),e}function onImageLoaded(e){return gLoadedTextures++,updateLoadingProgress(),e}function updateLoadingProgress(){let e=document.getElementById("image-progress");const t=gNumTextures>0?gNumTextures:"?";e.innerHTML="Loading images: "+gLoadedTextures+"/"+t}function isRendererUnsupported(){let e=document.getElementById("Loading"),t=document.getElementsByTagName("canvas")[0].getContext("webgl2");return t?!t.getExtension("WEBGL_debug_renderer_info")&&(e.innerHTML="Error: Could not fetch renderer info. Is your machine equipped with a discrete GPU?",!0):(e.innerHTML="Error: WebGL2 context not found. Is your machine equipped with a discrete GPU?",!0)}function sleep(e){return new Promise((t=>setTimeout(t,e)))}function submodelAssetPath(e,t){let r="";if(gUseSubmodel){return r=`../sm_${String(e).padStart(3,"0")}`,null==t?r:`${r}/${t}`}return t}function positionToSubmodel(e,t){if(0==gUseSubmodel)return 0;if(gSubmodelForceIndex>=0)return gSubmodelForceIndex;let r=new THREE.Vector3(-e.x,e.z,e.y),a=2/t.submodel_voxel_size,n=r.addScalar(1).divideScalar(2);n=n.multiplyScalar(a);let s=n.floor().clampScalar(0,a-1);const i=(s.x*a+s.y)*a+s.z;return t.sm_to_params[i]}function submodelCenter(e,t){if(0==gUseSubmodel)return new THREE.Vector3(0,0,0);let r=t.submodel_voxel_size,a=2/r,n=t.params_to_sm[e],s=n%a,i=(n-s)/a%a,o=(n-s-i*a)/a/a;return o=a-1-o,[i,s]=[s,i],new THREE.Vector3((o+.5)*r-1,(i+.5)*r-1,(s+.5)*r-1)}function submodelTransform(e,t){const r=submodelCenter(e,t),a=t.submodel_scale;let n=new THREE.Matrix4;n.makeScale(a,a,a);let s=new THREE.Matrix4;return s.makeTranslation(-r.x,-r.y,-r.z),submodel_matrix=new THREE.Matrix4,submodel_matrix.multiplyMatrices(n,s),submodel_matrix}async function fetchAndRetryIfNecessary(e){const t=await e();return 429===t.status?(await sleep(500),fetchAndRetryIfNecessary(e)):t}function loadAsset(e){return new Promise((t=>{gLoadAssetsWorker.submit({url:e},t)}))}function mergeSlices(e,t,r){let a=e.sliceAssets.map((e=>e.asset));return Promise.all(a).then((a=>{let n=range(a.length).map((t=>({...e.sliceAssets[t],asset:a[t]}))),s={asset:{...e,sliceAssets:n},src:t,dst:r,fn:"mergeSlices"};return new Promise((e=>{gCopySliceWorker.submit(s,e)}))}))}function mergeSparseGridDensity(e){let t=e=>Promise.all(e.sliceAssets.map((e=>e.asset))),r=[t(e.rgbAndDensityAsset),t(e.featuresAsset)];return Promise.all(r).then((t=>{let r=t[0],a=t[1],n=(e,t)=>{let r=range(t.length).map((r=>({...e.sliceAssets[r],asset:t[r]})));return{...e,sliceAssets:r}},s=n(e.rgbAndDensityAsset,r),i=n(e.featuresAsset,a),o={asset:{assetType:e.assetType,rgbAndDensityAsset:s,featuresAsset:i},fn:"mergeSparseGridDensity"};return new Promise((e=>{gCopySliceWorker.submit(o,e)}))}))}function getFieldOrDefault(e,t,r){let a=e[t];return null==a?r:a}async function loadTextFile(e){try{const t=cleanPath(e),r=await fetch("http://localhost:3001/generate-signed-url",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({dirUrl:t})});if(!r.ok)throw new Error(`Erreur lors de la génération de l'URL signée: ${r.status}`);const{url:a}=await r.json();console.log("Tentative de chargement du fichier texte depuis:",a);const n=await fetch(a);if(!n.ok)throw new Error(`Erreur lors du téléchargement du fichier: ${n.status}`);const s=await n.text();return console.log("Contenu du fichier texte chargé depuis",a,":",s),s}catch(t){throw console.error(`Erreur lors de la récupération du fichier texte depuis ${e}:`,t),t}}async function loadJSONFile(e){try{const t=cleanPath(e),r=await fetch("http://localhost:3001/generate-signed-url",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({dirUrl:t})});if(console.log("Chemin avant génération de l'URL signée:",t),!r.ok)throw new Error(`Erreur lors de la génération de l'URL signée: ${r.status}`);const{url:a}=await r.json();console.log("Tentative de chargement du fichier JSON depuis:",a);const n=await fetch(a);if(!n.ok)throw new Error(`Erreur lors du téléchargement du fichier JSON: ${n.status}`);const s=await n.json();return console.log("Contenu du fichier JSON chargé depuis",a,":",s),s}catch(t){throw console.error(`Erreur lors de la récupération du fichier JSON depuis ${e}:`,t),t}}function cleanPath(e){const t=e.split("/"),r=[];for(let e=0;e<t.length;e++)".."===t[e]?r.length&&r.pop():"."!==t[e]&&""!==t[e]&&r.push(t[e]);return r.join("/")}class Router{constructor(e,t){this.dirUrl=e,this.filenameToLink=t}translate(e){if(null!=this.filenameToLink)return this.filenameToLink[e];return`${this.cleanPath(this.dirUrl)}/${e}`}cleanPath(e){const t=e.split("/"),r=[];for(let e=0;e<t.length;e++)".."===t[e]?r.length&&r.pop():"."!==t[e]&&""!==t[e]&&r.push(t[e]);return r.join("/")}}const Format={RED:{numChannels:1},LUMINANCE_ALPHA:{numChannels:2},RGB:{numChannels:3},RGBA:{numChannels:4}},GridTextureSource={RGBA_FROM_RGBA:{format:Format.RGBA,channels:[0,1,2,3]},RGB_FROM_RGBA:{format:Format.RGBA,channels:[0,1,2]},RGB_FROM_RGB:{format:Format.RGB,channels:[0,1,2]},ALPHA_FROM_RGBA:{format:Format.RGBA,channels:[3]},RED_FROM_RED:{format:Format.RED,channels:[0]},LA_FROM_LUMINANCE_ALPHA:{format:Format.LUMINANCE_ALPHA,channels:[0,1]}},GridTextureDestination={RED_IN_RED:{format:Format.RED,channels:[0]},RGB_IN_RGB:{format:Format.RGB,channels:[0,1,2]},RGBA_IN_RGBA:{format:Format.RGBA,channels:[0,1,2,3]},LA_IN_LUMINANCE_ALPHA:{format:Format.LUMINANCE_ALPHA,channels:[0,1]},LUMINANCE_IN_LUMINANCE_ALPHA:{format:Format.LUMINANCE_ALPHA,channels:[0]},ALPHA_IN_LUMINANCE_ALPHA:{format:Format.LUMINANCE_ALPHA,channels:[1]}};let gSceneAccumulate=null,gLowResBlitCamera=null,gHighResBlitCamera=null,gOldMatrixWorld=null,gOldProjectionMatrix=null,gFrameIndex=0,gLowResTexture=null;function createAccumulateMaterial(e,t,r,a){return new THREE.ShaderMaterial({uniforms:{mapLowRes:{value:e},mapHistory:{value:t},lowResolution:{value:r},highResolution:{value:a},jitterOffset:{value:new THREE.Vector2(0,0)},emaAlpha:{value:.15}},vertexShader:accumulateVertexShader,fragmentShader:accumulateFragmentShader})}const gAccumulationTextures=[null,null],normalizeVertexShader="\nvarying vec2 vUv;\nvoid main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n",normalizeFragmentShader="\nvarying vec2 vUv;\nuniform sampler2D map;\nvoid main() {\n gl_FragColor = texture2D(map, vUv);\n if (gl_FragColor.a > 0.0) {\n gl_FragColor.rgb /= gl_FragColor.a;\n }\n gl_FragColor.a = 1.0;\n}\n";function createNormalizeMaterial(e){return new THREE.ShaderMaterial({uniforms:{map:{value:e}},vertexShader:normalizeVertexShader,fragmentShader:normalizeFragmentShader})}let gSceneNormalize=null;const accumulateVertexShader="\nvarying vec2 vUv;\nvoid main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n",accumulateFragmentShader="\nvarying vec2 vUv;\nuniform vec2 lowResolution;\nuniform vec2 highResolution;\nuniform vec2 jitterOffset;\nuniform float emaAlpha;\n\nuniform sampler2D mapLowRes;\nuniform sampler2D mapHistory;\n\nfloat pixelFilter(vec2 pixelCenter, vec2 sampleCenter) {\n vec2 delta = pixelCenter - sampleCenter;\n float squaredNorm = dot(delta, delta);\n return exp(-2.29 * squaredNorm);\n}\n\nvoid main() {\n // First we need to compute the coordinates of the pixel centers\n // in the low resolution grid by compensating for the camera jitter.\n // Note that the offset is defined in clip space [-1,1]^2, so we need\n // to multiply it by 0.5 to make it valid in texture space [0,1]^2.\n vec2 compensatedUnitCoords = vUv - jitterOffset * 0.5;\n\n // Now compute the integer coordinates in the low resolution grid for each\n // adjacent texel.\n ivec2 lowResCoords00 = ivec2(compensatedUnitCoords * lowResolution - 0.5);\n ivec2 lowResCoords01 = ivec2(0, 1) + lowResCoords00;\n ivec2 lowResCoords10 = ivec2(1, 0) + lowResCoords00;\n ivec2 lowResCoords11 = ivec2(1, 1) + lowResCoords00;\n\n float mask00 =\n min(lowResCoords00.x, lowResCoords00.y) < 0 ||\n lowResCoords00.x >= int(lowResolution.x) ||\n lowResCoords00.y >= int(lowResolution.y) ? 0.0 : 1.0;\n float mask01 =\n min(lowResCoords01.x, lowResCoords01.y) < 0 ||\n lowResCoords01.x >= int(lowResolution.x) ||\n lowResCoords01.y >= int(lowResolution.y) ? 0.0 : 1.0;\n float mask10 =\n min(lowResCoords10.x, lowResCoords10.y) < 0 ||\n lowResCoords10.x >= int(lowResolution.x) ||\n lowResCoords10.y >= int(lowResolution.y) ? 0.0 : 1.0;\n float mask11 =\n min(lowResCoords11.x, lowResCoords11.y) < 0 ||\n lowResCoords11.x >= int(lowResolution.x) ||\n lowResCoords11.y >= int(lowResolution.y) ? 0.0 : 1.0;\n\n // We also need to keep track of the high resolution counterparts of these\n // coordinates, so we can compute the pixel reconstruction filter weights.\n vec2 compensatedHighResCoords = highResolution * compensatedUnitCoords;\n vec2 highResCoords00 =\n highResolution * (vec2(lowResCoords00) + 0.5) / lowResolution;\n vec2 highResCoords01 =\n highResolution * (vec2(lowResCoords01) + 0.5) / lowResolution;\n vec2 highResCoords10 =\n highResolution * (vec2(lowResCoords10) + 0.5) / lowResolution;\n vec2 highResCoords11 =\n highResolution * (vec2(lowResCoords11) + 0.5) / lowResolution;\n\n vec4 lowResColor = vec4(0.0, 0.0, 0.0, 0.0);\n lowResColor += mask00 * vec4(\n texelFetch(mapLowRes,lowResCoords00, 0).rgb, 1.0) *\n pixelFilter(compensatedHighResCoords, highResCoords00);\n lowResColor += mask01 * vec4(\n texelFetch(mapLowRes, lowResCoords01, 0).rgb, 1.0) *\n pixelFilter(compensatedHighResCoords, highResCoords01);\n lowResColor += mask10 * vec4(\n texelFetch(mapLowRes, lowResCoords10, 0).rgb, 1.0) *\n pixelFilter(compensatedHighResCoords, highResCoords10);\n lowResColor += mask11 * vec4(\n texelFetch(mapLowRes, lowResCoords11, 0).rgb, 1.0) *\n pixelFilter(compensatedHighResCoords, highResCoords11);\n\n vec4 historyColor = texture2D(mapHistory, vUv);\n gl_FragColor = emaAlpha * lowResColor + (1.0 - emaAlpha) * historyColor;\n}\n";function setupProgressiveRendering(e,t){gHighResBlitCamera=new THREE.OrthographicCamera(e.offsetWidth/-2,e.offsetWidth/2,e.offsetHeight/2,e.offsetHeight/-2,-1e4,1e4),gHighResBlitCamera.position.z=100;let r=new THREE.PlaneBufferGeometry(e.offsetWidth,e.offsetHeight);gLowResTexture=new THREE.WebGLRenderTarget(Math.trunc(e.offsetWidth/t),Math.trunc(e.offsetHeight/t),{minFilter:THREE.NearestFilter,magFilter:THREE.NearestFilter,type:THREE.UnsignedByteType,format:THREE.RGBFormat}),gAccumulationTextures[0]=new THREE.WebGLRenderTarget(e.offsetWidth,e.offsetHeight,{minFilter:THREE.NearestFilter,magFilter:THREE.NearestFilter,type:THREE.FloatType,format:THREE.RGBAFormat}),gAccumulationTextures[1]=new THREE.WebGLRenderTarget(e.offsetWidth,e.offsetHeight,{minFilter:THREE.NearestFilter,magFilter:THREE.NearestFilter,type:THREE.FloatType,format:THREE.RGBAFormat});let a=new THREE.Mesh(r,createAccumulateMaterial(gLowResTexture.texture,gAccumulationTextures[1],new THREE.Vector2(Math.trunc(e.offsetWidth/t),Math.trunc(e.offsetHeight/t)),new THREE.Vector2(e.offsetWidth,e.offsetHeight)));a.position.z=-100,gSceneAccumulate=new THREE.Scene,gSceneAccumulate.add(a),gSceneAccumulate.autoUpdate=!1;let n=new THREE.Mesh(r,createNormalizeMaterial(gAccumulationTextures[0].texture));n.position.z=-100,gSceneNormalize=new THREE.Scene,gSceneNormalize.add(n),gSceneNormalize.autoUpdate=!1,gLowResBlitCamera=new THREE.OrthographicCamera(Math.trunc(e.offsetWidth/t)/-2,Math.trunc(e.offsetWidth/t)/2,Math.trunc(e.offsetHeight/t)/2,Math.trunc(e.offsetHeight/t)/-2,-1e4,1e4),gLowResBlitCamera.position.z=100,gOldProjectionMatrix=gCamera.projectionMatrix.clone(),gOldMatrixWorld=gCamera.matrixWorld.clone()}function renderFrame(e){e||(e=gCamera.projectionMatrix.clone());let t=new THREE.Matrix4;t.getInverse(e);let r=gCamera.matrixWorld;submodel_T_world=gSubmodelTransform,submodel_T_camera=new THREE.Matrix4,submodel_T_camera.multiplyMatrices(submodel_T_world,r);let a=getRayMarchScene();a.children[0].material.uniforms.world_T_cam.value=submodel_T_camera,a.children[0].material.uniforms.cam_T_clip.value=t,a.children[0].material.uniforms.displayMode.value=gDisplayMode-0,gRenderer.clear(),gRenderer.render(a,gLowResBlitCamera)}function renderProgressively(){const e=gAccumulationTextures[0].width/gLowResTexture.width;if(1==e)return void renderFrame();let t=!gCamera.projectionMatrix.equals(gOldProjectionMatrix)||!gCamera.matrixWorld.equals(gOldMatrixWorld);const r=e%2==0;let a=.5,n=Math.trunc(e/2);r||(a=.5,n+=1);let s=[],i=[];for(let t=0;t<n;t++)for(let r=0;r<n;r++)s.push((a+t)/e),i.push((a+r)/e),s.push(-(a+t)/e),i.push((a+r)/e),s.push((a+t)/e),i.push(-(a+r)/e),s.push(-(a+t)/e),i.push(-(a+r)/e);let o=gFrameIndex%s.length,l=s[o],c=i[o];gLowResBlitCamera.left=l+gLowResTexture.width/-2,gLowResBlitCamera.right=l+gLowResTexture.width/2,gLowResBlitCamera.top=c+gLowResTexture.height/2,gLowResBlitCamera.bottom=c+gLowResTexture.height/-2,gLowResBlitCamera.updateProjectionMatrix(),l*=2/gLowResTexture.width,c*=2/gLowResTexture.height;let u=gCamera.projectionMatrix.clone();u.elements[8]+=l,u.elements[9]+=c,gRenderer.setRenderTarget(gLowResTexture),renderFrame(u);let d=Math.min(1,.7/s.length);t&&(gFrameIndex=0,d=1);let p=gFrameIndex%2,g=1-p;gRenderer.setRenderTarget(gAccumulationTextures[p]),gSceneAccumulate.children[0].material.uniforms.mapHistory.value=gAccumulationTextures[g].texture,gSceneAccumulate.children[0].material.uniforms.jitterOffset.value=new THREE.Vector2(l,c),gSceneAccumulate.children[0].material.uniforms.emaAlpha.value=d,gRenderer.clear(),gRenderer.render(gSceneAccumulate,gHighResBlitCamera),gRenderer.setRenderTarget(null),gSceneNormalize.children[0].material.uniforms.map.value=gAccumulationTextures[p].texture,gRenderer.clear(),gRenderer.render(gSceneNormalize,gHighResBlitCamera),gFrameIndex++,gOldProjectionMatrix=gCamera.projectionMatrix.clone(),gOldMatrixWorld=gCamera.matrixWorld.clone()}function computeTrilerpLocationsAndWeights(e,t,r){let a=(new THREE.Vector3).copy(e);a.addScalar(1),a.divideScalar(2),a.multiplyScalar(r),a.subScalar(.5);const n=(new THREE.Vector3).copy(a).floor(),s=(new THREE.Vector3).copy(a).ceil();let i=t.x>0?s.x:n.x,o=t.y>0?s.y:n.y,l=t.z>0?s.z:n.z;i=Math.min(Math.max(i,0),r-1),o=Math.min(Math.max(o,0),r-1),l=Math.min(Math.max(l,0),r-1),i=r-1-i,[o,l]=[l,o];const c=(l*r+o)*r+i;let u=a.x-n.x,d=a.y-n.y,p=a.z-n.z;0==t.x&&(u=1-u),0==t.y&&(d=1-d),0==t.z&&(p=1-p);return[c,u*d*p]}function trilerpDeferredMlpKernel(e,t,r){let a,n,s;if(gDeferredMlp["ResampleDense_"+t+"/kernel"]){const i=gDeferredMlp["ResampleDense_"+t+"/kernel"],o=i.data,l=i.shape[1],c=i.shape[4],u=i.shape[5];a=makeMultipleOf(u,4),n=makeMultipleOf(c,4),s=new Float32Array(n*a);let d=(new THREE.Vector3).copy(r);d.divideScalar(getSubmodelScaleFactor(e));const p=e*l*l*l*c*u;for(let e=0;e<2;e++)for(let t=0;t<2;t++)for(let r=0;r<2;r++){const[i,g]=computeTrilerpLocationsAndWeights(d,new THREE.Vector3(e,t,r),l),m=p+c*u*i;for(let i=0;i<a;i++)for(let a=0;a<n;a++){let l=i*n+a,d=0;a<c&&i<u&&(d=o[m+a*u+i]),e+t+r===0?s[l]=g*d:s[l]+=g*d}}}else{const e=gDeferredMlp["Dense_"+t+"/kernel"],r=e.data,i=e.shape[0],o=e.shape[1];a=makeMultipleOf(o,4),n=makeMultipleOf(i,4),s=new Float32Array(n*a);for(let e=0;e<a;e++)for(let t=0;t<n;t++){t<i&&e<o&&(s[e*n+t]=r[t*o+e])}}let i=new Float32Array(n*a);for(let e=0;e<n;e+=4)for(let t=0;t<a;t++)for(let r=0;r<4;r++)i[e/4*a*4+4*t+r]=s[e/4*4+t*(n/4*4)+r];let o=new THREE.DataTexture(i,1,n*a/4,THREE.RGBAFormat);return o.magFilter=THREE.NearestFilter,o.minFilter=THREE.NearestFilter,o.type=THREE.FloatType,o}function trilerpDeferredMlpBiases(e,t,r){let a;if(gDeferredMlp["ResampleDense_"+t+"/bias"]){const n=gDeferredMlp["ResampleDense_"+t+"/bias"],s=n.data,i=n.shape[1],o=n.shape[4],l=makeMultipleOf(o,4);a=new Array(l/4);let c=(new THREE.Vector3).copy(r);c.divideScalar(getSubmodelScaleFactor(e));const u=e*i*i*i*o;for(let e=0;e<2;e++)for(let t=0;t<2;t++)for(let r=0;r<2;r++){const[n,d]=computeTrilerpLocationsAndWeights(c,new THREE.Vector3(e,t,r),i),p=u+o*n;for(let n=0;n<l/4;++n){let i=new THREE.Vector4(0,0,0,0);for(let e=0;e<4;e++)4*n+0<l&&i.setComponent(e,s[p+4*n+e]);i.multiplyScalar(d),e+t+r===0?a[n]=i:a[n].add(i)}}}else{const e=gDeferredMlp["Dense_"+t+"/bias"],r=e.data,n=makeMultipleOf(e.shape[0],4);a=new Array(n/4);for(let e=0;e<n/4;++e){let t=new THREE.Vector4(0,0,0,0);for(let a=0;a<4;a++)4*e+0<n&&t.setComponent(a,r[4*e+a]);a[e]=t}}return a}function rewriteViewDependenceDefinitions(e,t){let r=getDeferredMlp();const a=r["ResampleDense_0/kernel"]?"ResampleDense_":"Dense_",n=r["ResampleDense_0/kernel"]?4:0;let s=t,i=["intermediate_one","intermediate_two","result"];for(let e=0;e<3;e++){let t=r[a+e+"/bias"].shape[n],o=`bias_${e}`,l=i[e],c=[];for(let e=0;e<t/4;e++)c.push(`${l}[${e}] = ${o}[${e}];`);let u=c.join(" ")+"\n";s=s.replace(new RegExp(`INITIALIZE_OUTPUT_ACTIVATIONS_${e}`,"g"),u)}let o=makeMultipleOf(r[a+"0/kernel"].shape[n],4),l=makeMultipleOf(r[a+"0/bias"].shape[n],4),c=makeMultipleOf(r[a+"1/bias"].shape[n],4),u=makeMultipleOf(r[a+"2/bias"].shape[n],4);return s=s.replace(new RegExp("NUM_CHANNELS_ZERO","g"),o),s=s.replace(new RegExp("NUM_POSENC_SCALES","g"),4..toString()),s=s.replace(new RegExp("NUM_CHANNELS_ONE","g"),l),s=s.replace(new RegExp("NUM_CHANNELS_TWO","g"),c),s=s.replace(new RegExp("NUM_CHANNELS_THREE","g"),u),s}function makeMultipleOf(e,t){return e%t==0?e:e+t-e%t}function setupInitialCameraPose(e,t){function r(e){var r,a,n;gCamera.position.x=e.position[0]+t.x,gCamera.position.y=e.position[1]+t.y,gCamera.position.z=e.position[2]+t.z,r=e.lookat[0]+t.x,a=e.lookat[1]+t.y,n=e.lookat[2]+t.z,gOrbitControls?(gOrbitControls.target.x=r,gOrbitControls.target.y=a,gOrbitControls.target.z=n):gMapControls?(gMapControls.target.x=gCamera.position.x+(r-gCamera.position.x)*gCamera.near,gMapControls.target.y=gCamera.position.y+(a-gCamera.position.y)*gCamera.near,gMapControls.target.z=gCamera.position.z+(n-gCamera.position.z)*gCamera.near):gCamera.lookAt(r,a,n)}initialPoses={default:{position:[0,0,0],lookat:[0,0,1]},gardenvase:{position:[-1.1868985500525444,.1898527233835131,-.04923970470097733],lookat:[-.05581392405861873,-.40202760746449473,.02985343723310108]},stump:{position:[0,.4,-.8],lookat:[0,-.3,0]},flowerbed:{position:[-.02402388218043944,.11825367482140309,.907525093384825],lookat:[.016306507293821822,-.15676691106539536,-.016192691610482132]},treehill:{position:[-.70994804046872,.19435986647308223,.30833533637897453],lookat:[.06327294888291587,-.13299740290200024,.0037554887097183934]},bicycle:{position:[-.4636408064933045,.49624791762954734,.8457540259646037],lookat:[.017170160491904368,-.24649043500978007,-.07787524806850904]},kitchenlego:{position:[-.5872864419408019,.05633623000443683,-.9472239198227385],lookat:[.07177184299031553,-.4020277194862108,.04850453170234236]},fulllivingroom:{position:[1.1539572663654272,-.006785278327404387,-.0972986385811351],lookat:[-.05581392405861873,-.40202760746449473,.02985343723310108]},kitchencounter:{position:[-.7006764413546107,.2255633917824672,-.46941182833135847],lookat:[.13197415755218864,-.4020278046227117,.09221809216932579]},officebonsai:{position:[-.4773314920559294,.05409730603092788,1.014304107335418],lookat:[.11970974858222336,-.40426664345968033,-.019801655674420764]}},r(initialPoses.default);for(let t in initialPoses)if(e.includes(t)){r(initialPoses[t]);break}gCamera.updateProjectionMatrix()}let gOrbitControls=null,gMapControls=null,gPointerLockControls=null,gKeyW=!1,gKeyA=!1,gKeyS=!1,gKeyD=!1,gKeyQ=!1,gKeyE=!1,gKeyShift=!1;const gClock=new THREE.Clock;function addHandlers(){let e=document.getElementById("shader-editor");document.addEventListener("keypress",(function(t){if("input"!==document.activeElement.tagName.toLowerCase()&&"textarea"!==document.activeElement.tagName.toLowerCase()&&document.activeElement!==e){if(32!==t.keyCode&&" "!==t.key&&"Spacebar"!==t.key||(gDisplayMode==DisplayModeType.DISPLAY_NORMAL?(gDisplayMode=DisplayModeType.DISPLAY_DIFFUSE,console.log("Displaying DIFFUSE")):gDisplayMode==DisplayModeType.DISPLAY_DIFFUSE?(gDisplayMode=DisplayModeType.DISPLAY_FEATURES,console.log("Displaying DISPLAY_FEATURES")):gDisplayMode==DisplayModeType.DISPLAY_FEATURES?(gDisplayMode=DisplayModeType.DISPLAY_VIEW_DEPENDENT,console.log("Displaying DISPLAY_VIEW_DEPENDENT")):gDisplayMode==DisplayModeType.DISPLAY_VIEW_DEPENDENT?(gDisplayMode=DisplayModeType.DISPLAY_COARSE_GRID,console.log("Displaying DISPLAY_COARSE_GRID")):(gDisplayMode=DisplayModeType.DISPLAY_NORMAL,console.log("Displaying DISPLAY_NORMAL")),t.preventDefault()),"r"===t.key){console.log("Recompile shader.");let r=getRayMarchScene().children[0].material;r.fragmentShader=e.value,r.needsUpdate=!0,t.preventDefault()}if("?"===t.key){let e=gCamera.getWorldPosition(new THREE.Vector3(0,0,0)),r=gCamera.getWorldQuaternion(new THREE.Quaternion);console.log(`\n// Camera Info:\ngCamera.position.set(${e.x}, ${e.y}, ${e.z});\ngCamera.quaternion.set(${r.x}, ${r.y}, ${r.z}, ${r.w});\n`),t.preventDefault()}}})),document.addEventListener("keydown",(function(t){if("input"===document.activeElement.tagName.toLowerCase()||"textarea"===document.activeElement.tagName.toLowerCase())return;if(document.activeElement===e)return;let r=t.key.toLowerCase();"w"===r&&(gKeyW=!0,t.preventDefault()),"a"===r&&(gKeyA=!0),"s"===r&&(gKeyS=!0,t.preventDefault()),"d"===r&&(gKeyD=!0,t.preventDefault()),"q"===r&&(gKeyQ=!0,t.preventDefault()),"e"===r&&(gKeyE=!0,t.preventDefault()),"Shift"===t.key&&(gKeyShift=!0,t.preventDefault())})),document.addEventListener("keyup",(function(t){if("input"===document.activeElement.tagName.toLowerCase()||"textarea"===document.activeElement.tagName.toLowerCase())return;if(document.activeElement===e)return;let r=t.key.toLowerCase();"w"===r&&(gKeyW=!1,t.preventDefault()),"a"===r&&(gKeyA=!1),"s"===r&&(gKeyS=!1,t.preventDefault()),"d"===r&&(gKeyD=!1,t.preventDefault()),"q"===r&&(gKeyQ=!1,t.preventDefault()),"e"===r&&(gKeyE=!1,t.preventDefault()),"Shift"===t.key&&(gKeyShift=!1,t.preventDefault())}))}function setupCameraControls(e,t){if(e&&"fps"==e){gPointerLockControls=new THREE.PointerLockControls(gCamera,t);let e=document.createElement("button");e.innerHTML="Commencer la visite !",e.classList.add("mouse-navigation-button"),e.addEventListener("click",(function(){gPointerLockControls.lock(),gPointerLockControls.connect(),e.classList.add("hidden")}),!1),gPointerLockControls.addEventListener("unlock",(function(){e.classList.remove("hidden")})),t.appendChild(e)}else e&&"map"==e?(gMapControls=new THREE.OrbitControls(gCamera,t),gMapControls.panSpeed=.5/gCamera.near,gMapControls.enableZoom=!1,gMapControls.screenSpacePanning=!1,gMapControls.mouseButtons={LEFT:THREE.MOUSE.ROTATE,RIGHT:THREE.MOUSE.PAN},gMapControls.touches={ONE:THREE.TOUCH.PAN,TWO:THREE.TOUCH.DOLLY_ROTATE}):(gOrbitControls=new THREE.OrbitControls(gCamera,t),gOrbitControls.screenSpacePanning=!0,gOrbitControls.zoomSpeed=.5)}function updateCameraControls(){if(gOrbitControls)gOrbitControls.update();else if(gMapControls)gMapControls.update();else if(gPointerLockControls){const e=gClock.getDelta();let t=.25;gKeyShift&&(t=1);let r=gCamera.getWorldDirection(new THREE.Vector3(0,0,0)),a=new THREE.Vector3(0,1,0);gKeyW&&(gCamera.position=gCamera.position.addScaledVector(r,e*t)),gKeyA&&gPointerLockControls.moveRight(-e*t),gKeyS&&(gCamera.position=gCamera.position.addScaledVector(r,-e*t)),gKeyD&&gPointerLockControls.moveRight(e*t),gKeyQ&&(gCamera.position=gCamera.position.addScaledVector(a,-e*t)),gKeyE&&(gCamera.position=gCamera.position.addScaledVector(a,e*t))}}let gIsCoolingDown=!1,gBenchmarkTimestamps=null,gFrameTimes=[],gBenchmarkCameras={},gBenchmarkCameraIndex=0;const gBenchmarkMethodName="blockmerf";let gBenchmarkSceneName=null,gSaveBenchmarkFrames=!1;function setupBenchmarkStats(e,t){gBenchmarkSceneName=e,gSaveBenchmarkFrames=t;let r=document.getElementById("benchmark-stats");r.style.display="block",r.addEventListener("click",(e=>{gBenchmark=!0}))}function clearBenchmarkStats(e){document.getElementById("benchmark-stats").innerHTML=""}function addBenchmarkRow(e){document.getElementById("benchmark-stats").innerHTML+=e+"\n"}function getBenchmarkStats(e){return document.getElementById("benchmark-stats").innerHTML}function loadBenchmarkCameras(e){const t=e.translate("test_frames.json"),r=loadJSONFile(t);r.catch((e=>{console.error("Could not load test frames from: "+t+", error: "+e)})),r.then((e=>{gBenchmarkCameras=e.test_frames}))}function setBenchmarkCameraPose(e,t){e.position.fromArray(gBenchmarkCameras[t].position),e.setRotationFromMatrix((new THREE.Matrix4).fromArray(gBenchmarkCameras[t].rotation)),e.projectionMatrix.fromArray(gBenchmarkCameras[t].projection)}function cooldownFrame(e){const t=.5*(1+Math.sin(e*Math.PI/1e3));let r=new THREE.Color("#FFFFFF");r.lerp(new THREE.Color("#A5C0E2"),t),gRenderer.setClearColor(r,1),gRenderer.clear(),gStats&&gStats.update(),gIsCoolingDown&&requestAnimationFrame(cooldownFrame)}function formatTimestampAsString(){const e=new Date,t=e.getHours().toString().padStart(2,"0"),r=e.getMinutes().toString().padStart(2,"0");return`${e.getFullYear()}_${e.getMonth()+1}_${e.getDate()}_${t}${r}`}function benchmarkPerformance(e){const t=Math.max(4,Math.ceil(100/gFrameMult)),r=Math.max(2,Math.ceil(.1*t));if(isLoading())return e;if(!gBenchmarkTimestamps&&!gIsCoolingDown){setBenchmarkCameraPose(gCamera,0),gBenchmarkTimestamps=[];let t=new THREE.Vector2;return gRenderer.getSize(t),clearBenchmarkStats(),addBenchmarkRow(`frame timestamps (ms) at ${t.x}x${t.y}`),addBenchmarkRow("cam_idx ; start ; end ; mean frame time"),e}if(gBenchmarkTimestamps.push(window.performance.now()),gBenchmarkTimestamps.length<t)return e;gSaveBenchmarkFrames&&(frameAsPng=gRenderer.domElement.toDataURL("image/png"),saveAs(frameAsPng,digits(gBenchmarkCameraIndex,4)+".png"));let a=gBenchmarkTimestamps.slice(r);const n=a.length,s=a[0],i=a.pop();let o=(i-s)/(gFrameMult*(n-1));if(gFrameTimes.push(o),addBenchmarkRow(`${gBenchmarkCameraIndex} ; ${s} ; ${i} ; ${o}`),++gBenchmarkCameraIndex>=gBenchmarkCameras.length){console.log(gFrameTimes.reduce(((e,t)=>e+t),0)/gFrameTimes.length),gBenchmark=!1;const t=new Blob([getBenchmarkStats()],{type:"text/plain;charset=utf-8"}),r="blockmerf_"+gBenchmarkSceneName+"_frameMult_"+gFrameMult+"_"+formatTimestampAsString()+".csv";return saveAs(t,r),e}return gBenchmarkTimestamps=[],setBenchmarkCameraPose(gCamera,gBenchmarkCameraIndex),e}let gSubmodelPanel=null,gVMemPanel=null,gStepMult=1,gExposure=null;function loadScene(e,t){let r;e&&e.includes(".json")?r=loadJSONFile(e):(r=Promise.resolve(null),console.error("dirUrl est null ou non valide. Le fichier Json est dans le dossier")),r.then((r=>{const a=new Router(e,r);console.log("router:",a);const n=a.translate("scene_params.json");console.log("sceneParamsUrl:",n);const s=loadJSONFile(n);return console.log("sceneParamsPromise:",s),t.loadBenchmarkCameras&&loadBenchmarkCameras(a),Promise.all([s,{router:a,filenameToLink:r}])})).then((e=>{const[t,r]=e;let a=0;gUseSubmodel=t.hasOwnProperty("num_local_submodels")&&t.num_local_submodels>1,gUseSubmodel&&(gSubmodelCount=t.num_local_submodels,a=t.sm_to_params[t.submodel_idx]);let n=[];for(let e=0;e<gSubmodelCount;++e){const a=t.params_to_sm[e],s=r.router.translate(submodelAssetPath(a,"scene_params.json"));n.push(loadJSONFile(s))}return Promise.all([{...r,initialSubmodelIndex:a},...n])})).then((r=>{let[a,...n]=r;for(let r=0;r<n.length;++r){n[r]=extend(n[r],t);const s=n[r].params_to_sm[r];let i=e;gUseSubmodel&&(i=`${i}/${submodelAssetPath(s)}`);let o=new Router(i,a.filenameToLink),l=initializeSceneContent(n[r],o);console.log(`spec for submodel #${r}:`,l.spec),registerSubmodelContent(r,l)}let s=a.initialSubmodelIndex;return setupInitialCameraPose(e,submodelCenter(s,getSubmodelContent(s).params)),Promise.all([s,initializeDeferredMlp(s)])})).then((([e,t])=>initializePingPongBuffers(e))).then((()=>requestAnimationFrame(renderNextFrame)))}let disableCameraControls=!1;function initFromParameters(){const e=new URL(window.location.href).searchParams;console.log(e);const t="nyc/sm_004";console.log(t);let r=e.get("quality"),a=parseInt(e.get("downscale")||1,10);const n=e.get("stepMult");n&&(gStepMult=parseInt(n,10));const s=e.get("frameMult");s&&(gFrameMult=parseInt(s,10));const i=e.get("exposure");i&&(gExposure=parseFloat(i));let o={};const l=e.get("benchmark");if(l&&("time"===l.toLowerCase()||"quality"===l.toLowerCase())){o.loadBenchmarkCameras=!0,r="high";const e=t.split("/").slice(-2);setupBenchmarkStats(e[0]+"_"+e[1],"quality"===l.toLowerCase())}const c=e.get("deferredMode");c&&(o.deferred_rendering_mode=c);const u=e.get("combineMode");u&&"concat_and_sum"===u&&(o.merge_features_combine_op="coarse_sum");const d=e.get("useBits");d&&(o.useBits="true"===d.toLowerCase());const p=e.get("useDistanceGrid");p&&(o.useDistanceGrid="true"===p.toLowerCase());const g=e.get("legacyGrids");g&&(o.legacyGrids="true"===g.toLowerCase());const m=e.get("activation");m&&(o.activation=m);const h=e.get("featureGating");h&&(o.feature_gating="true"===h.toLowerCase());const f=e.get("submodelCacheSize");f&&(gSubmodelCacheSize=Number(f));const y=e.get("mergeSlices");y&&(o.merge_slices="true"==y);const _=e.get("backgroundColor");_&&(o.backgroundColor="#"+_);const T=document.createElement("div");T.classList.add("view");document.getElementById("viewspacecontainer").appendChild(T);const{width:x,height:S}=function(e){const t=getComputedStyle(e);return{width:parseInt(t.width,10),height:parseInt(t.height,10)}}(T);T.style.width=`${x}px`,T.style.height=`${S}px`,console.log("Width:",x,"Height:",S);const R=e.get("mouseMode")||"orbit";let E=.99;if(!e.get("downscale")&&r){let e=x*S;for("phone"==r?(e=135e3,E=.8):"low"==r?(e=15e4,E=.8):"medium"==r&&(e=768e3,E=.95);x*S/a>e;)a++;console.log("Automatically chose a downscaling factor of "+a)}o.useLargerStepsWhenOccluded=!1,o.step_size_visibility_delay=E;const b=parseFloat(e.get("near")||.01),C=parseFloat(e.get("vfovy")||40),w=document.querySelector(".viewspace");w.textContent="",w.appendChild(T);let A=document.createElement("canvas");T.appendChild(A),A.style.width="100%",A.style.height="100%",A.style.border=getComputedStyle(T).border,A.style.borderRadius=getComputedStyle(T).borderRadius,A.style.boxSizing=getComputedStyle(T).boxSizing,gStats=Stats(),gStats.dom.style.position="absolute",gStats.dom.style.display="none",w.appendChild(gStats.dom),gSubmodelPanel=gStats.addPanel(new Stats.Panel("SM","#0ff","#002")),gSubmodelPanel.update(getActiveSubmodelIndex()),gVMemPanel=gStats.addPanel(new Stats.Panel("MB VRAM","#0ff","#002")),gVMemPanel.update(0),gStats.showPanel(0);let v=A.getContext("webgl2",{powerPreference:"high-performance",alpha:!1,stencil:!0,precision:"highp",depth:!0,antialias:!1,desynchronized:!1,preserveDrawingBuffer:l&&"quality"===l.toLowerCase()});v.enable(v.DEPTH_TEST),v.depthFunc(v.LEQUAL),v.pixelStorei(v.UNPACK_ALIGNMENT,1),v.viewport(0,0,A.width,A.height),gRenderer=new THREE.WebGLRenderer({canvas:A,context:v}),gCamera=new THREE.PerspectiveCamera(C,Math.trunc(T.offsetWidth/a)/Math.trunc(T.offsetHeight/a),b,2e3),gCamera.updateProjectionMatrix(),window.sceneCamera=gCamera,setupProgressiveRendering(T,a),gRenderer.autoClear=!1,gRenderer.setSize(T.offsetWidth,T.offsetHeight),gRenderer.setClearColor(0,1),setupCameraControls(R,T),setupViewport(Math.trunc(T.offsetWidth/a),Math.trunc(T.offsetHeight/a)),loadScene(t,o)}let sphereAdded=!1;function renderNextFrame(e){garbageCollectSubmodelPayloads();let t=positionToSubmodel(gCamera.position,getActiveSubmodelContent().params);setCurrentRayMarchScene(t),t=getActiveSubmodelIndex();let r=getSubmodelContent(t).params;for(let e=0;e<gFrameMult;++e){gSubmodelTransform=submodelTransform(t,r),gSubmodelPanel.update(t),gVMemPanel.update(getCurrentTextureUsageInBytes()/1e6),disableCameraControls||updateCameraControls(),gBenchmark||gCamera.updateProjectionMatrix(),gCamera.updateMatrixWorld();const e=submodelCenter(t,r),a=getSubmodelScale(t);let n=(new THREE.Vector3).copy(gCamera.position);n.sub(e),n.multiplyScalar(a);let s=getRayMarchScene().children[0].material.uniforms;s.weightsZero.value&&s.weightsZero.value.dispose(),s.weightsOne.value&&s.weightsOne.value.dispose(),s.weightsTwo.value&&s.weightsTwo.value.dispose(),s.bias_0.value=trilerpDeferredMlpBiases(t,0,n),s.bias_1.value=trilerpDeferredMlpBiases(t,1,n),s.bias_2.value=trilerpDeferredMlpBiases(t,2,n),s.weightsZero.value=trilerpDeferredMlpKernel(t,0,n),s.weightsOne.value=trilerpDeferredMlpKernel(t,1,n),s.weightsTwo.value=trilerpDeferredMlpKernel(t,2,n),gRenderer.clear(),renderProgressively(),gRenderer.render(gSphereScene,gCamera)}gStats.update();let a=()=>{requestAnimationFrame(renderNextFrame)};gBenchmark&&(a=benchmarkPerformance(a)),a()}function start(){initFromParameters(),addHandlers(),gCamera&&gRenderer?(addInteractionPlane(),setupNewPlaneGizmo(newPlane),setupMouseHover(),window.addEventListener("mousemove",onMouseMove,!1),window.addEventListener("mousedown",onMouseDown,!1),window.addEventListener("mouseup",onMouseUp,!1)):console.error("gCamera ou gRenderer non initialisés.")}window.onload=start;
.history/combined_20241201141501.js ADDED
The diff for this file is too large to render. See raw diff
 
.history/combined_20241201141504.js ADDED
The diff for this file is too large to render. See raw diff
 
.history/copyslices.worker_20241118132102.js ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2024 The Google Research Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ /**
16
+ * Web worker responsible for copying bytes from sliced RGBA arrays to other
17
+ * targets.
18
+ */
19
+
20
+ importScripts("utils.js");
21
+
22
+ /**
23
+ * Copy asset.asset's contents into dstData using the format described by src &
24
+ * dst.
25
+ */
26
+ async function copySliceToBuffer(dstData, asset, src, dst) {
27
+ console.assert(src.channels.length == dst.channels.length, src, dst);
28
+
29
+ // Determine the offset for the output for this slice. Assume that each
30
+ // slice has the same shape.
31
+ let numPixels = product(asset.shape);
32
+ let baseOutOffset = numPixels * dst.format.numChannels * asset.sliceIndex;
33
+
34
+ // Wait for data to be ready.
35
+ let srcData = await asset.asset;
36
+
37
+ // Copy this asset's contents into dstData.
38
+ for (let px = 0; px < numPixels; ++px) {
39
+ // Buffer offsets for this pixel.
40
+ let inOffset = px * src.format.numChannels;
41
+ let outOffset = baseOutOffset + px * dst.format.numChannels;
42
+ for (let i = 0; i < src.channels.length; ++i) {
43
+ let inChannel = src.channels[i];
44
+ let outChannel = dst.channels[i];
45
+ dstData[outOffset + outChannel] = srcData[inOffset + inChannel];
46
+ }
47
+ }
48
+ }
49
+
50
+
51
+ /**
52
+ * Process an asset of type *_slices.
53
+ */
54
+ function processSlices(e) {
55
+ const i = e.data.i;
56
+ let { asset, src, dst } = e.data.request;
57
+
58
+ let numPixels = product(asset.shape);
59
+ let result = new Uint8Array(numPixels * dst.format.numChannels);
60
+
61
+ let promises = asset.sliceAssets.map((sliceAsset) => {
62
+ return copySliceToBuffer(result, sliceAsset, src, dst);
63
+ });
64
+
65
+ return Promise.all(promises).then(() => {
66
+ self.postMessage({i: i, result: result}, [result.buffer]);
67
+ });
68
+ }
69
+
70
+
71
+ /**
72
+ * Process sparse grid's density.
73
+ */
74
+ function processSparseGridDensity(e) {
75
+ const i = e.data.i;
76
+ let { asset } = e.data.request;
77
+
78
+ let numSlices = asset.rgbAndDensityAsset.numSlices;
79
+ console.assert(asset.rgbAndDensityAsset.numSlices == numSlices, asset);
80
+ console.assert(asset.featuresAsset.numSlices == numSlices, asset);
81
+
82
+ // Create a buffer for a luminance-alpha texture.
83
+ let result = new Uint8Array(product(asset.rgbAndDensityAsset.shape) * 2);
84
+
85
+ // Populate texture as assets arrive.
86
+ let promises = range(numSlices).map((i) => {
87
+ let rgbSliceAsset = asset.rgbAndDensityAsset.sliceAssets[i];
88
+ let featuresSliceAsset = asset.featuresAsset.sliceAssets[i];
89
+
90
+ // Copy density features to buffer. This requires merging the alpha values
91
+ // from two different data sources.
92
+ let copyLuminance = copySliceToBuffer(
93
+ result,
94
+ rgbSliceAsset,
95
+ GridTextureSource.ALPHA_FROM_RGBA,
96
+ GridTextureDestination.LUMINANCE_IN_LUMINANCE_ALPHA,
97
+ );
98
+
99
+ let copyAlpha = copySliceToBuffer(
100
+ result,
101
+ featuresSliceAsset,
102
+ GridTextureSource.ALPHA_FROM_RGBA,
103
+ GridTextureDestination.ALPHA_IN_LUMINANCE_ALPHA,
104
+ );
105
+
106
+ return Promise.all([copyLuminance, copyAlpha]);
107
+ });
108
+
109
+ return Promise.all(promises).then(() => {
110
+ self.postMessage({i: i, result: result}, [result.buffer]);
111
+ });
112
+ }
113
+
114
+ /**
115
+ * Main entry point.
116
+ */
117
+ function main(e) {
118
+ if (e.data.request.fn == 'mergeSlices') {
119
+ return processSlices(e);
120
+ } else if (e.data.request.fn == 'mergeSparseGridDensity') {
121
+ return processSparseGridDensity(e);
122
+ } else {
123
+ throw new Error(`Unrecognized request`, e.data.request);
124
+ }
125
+ }
126
+
127
+ // main() is called every time a new message comes in.
128
+ self.onmessage = main;
129
+
.history/copyslices.worker_20241204081957.js ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2024 The Google Research Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ /**
16
+ * Web worker responsible for copying bytes from sliced RGBA arrays to other
17
+ * targets.
18
+ */
19
+
20
+ importScripts("publicutils.js");
21
+
22
+ /**
23
+ * Copy asset.asset's contents into dstData using the format described by src &
24
+ * dst.
25
+ */
26
+ async function copySliceToBuffer(dstData, asset, src, dst) {
27
+ console.assert(src.channels.length == dst.channels.length, src, dst);
28
+
29
+ // Determine the offset for the output for this slice. Assume that each
30
+ // slice has the same shape.
31
+ let numPixels = product(asset.shape);
32
+ let baseOutOffset = numPixels * dst.format.numChannels * asset.sliceIndex;
33
+
34
+ // Wait for data to be ready.
35
+ let srcData = await asset.asset;
36
+
37
+ // Copy this asset's contents into dstData.
38
+ for (let px = 0; px < numPixels; ++px) {
39
+ // Buffer offsets for this pixel.
40
+ let inOffset = px * src.format.numChannels;
41
+ let outOffset = baseOutOffset + px * dst.format.numChannels;
42
+ for (let i = 0; i < src.channels.length; ++i) {
43
+ let inChannel = src.channels[i];
44
+ let outChannel = dst.channels[i];
45
+ dstData[outOffset + outChannel] = srcData[inOffset + inChannel];
46
+ }
47
+ }
48
+ }
49
+
50
+
51
+ /**
52
+ * Process an asset of type *_slices.
53
+ */
54
+ function processSlices(e) {
55
+ const i = e.data.i;
56
+ let { asset, src, dst } = e.data.request;
57
+
58
+ let numPixels = product(asset.shape);
59
+ let result = new Uint8Array(numPixels * dst.format.numChannels);
60
+
61
+ let promises = asset.sliceAssets.map((sliceAsset) => {
62
+ return copySliceToBuffer(result, sliceAsset, src, dst);
63
+ });
64
+
65
+ return Promise.all(promises).then(() => {
66
+ self.postMessage({i: i, result: result}, [result.buffer]);
67
+ });
68
+ }
69
+
70
+
71
+ /**
72
+ * Process sparse grid's density.
73
+ */
74
+ function processSparseGridDensity(e) {
75
+ const i = e.data.i;
76
+ let { asset } = e.data.request;
77
+
78
+ let numSlices = asset.rgbAndDensityAsset.numSlices;
79
+ console.assert(asset.rgbAndDensityAsset.numSlices == numSlices, asset);
80
+ console.assert(asset.featuresAsset.numSlices == numSlices, asset);
81
+
82
+ // Create a buffer for a luminance-alpha texture.
83
+ let result = new Uint8Array(product(asset.rgbAndDensityAsset.shape) * 2);
84
+
85
+ // Populate texture as assets arrive.
86
+ let promises = range(numSlices).map((i) => {
87
+ let rgbSliceAsset = asset.rgbAndDensityAsset.sliceAssets[i];
88
+ let featuresSliceAsset = asset.featuresAsset.sliceAssets[i];
89
+
90
+ // Copy density features to buffer. This requires merging the alpha values
91
+ // from two different data sources.
92
+ let copyLuminance = copySliceToBuffer(
93
+ result,
94
+ rgbSliceAsset,
95
+ GridTextureSource.ALPHA_FROM_RGBA,
96
+ GridTextureDestination.LUMINANCE_IN_LUMINANCE_ALPHA,
97
+ );
98
+
99
+ let copyAlpha = copySliceToBuffer(
100
+ result,
101
+ featuresSliceAsset,
102
+ GridTextureSource.ALPHA_FROM_RGBA,
103
+ GridTextureDestination.ALPHA_IN_LUMINANCE_ALPHA,
104
+ );
105
+
106
+ return Promise.all([copyLuminance, copyAlpha]);
107
+ });
108
+
109
+ return Promise.all(promises).then(() => {
110
+ self.postMessage({i: i, result: result}, [result.buffer]);
111
+ });
112
+ }
113
+
114
+ /**
115
+ * Main entry point.
116
+ */
117
+ function main(e) {
118
+ if (e.data.request.fn == 'mergeSlices') {
119
+ return processSlices(e);
120
+ } else if (e.data.request.fn == 'mergeSparseGridDensity') {
121
+ return processSparseGridDensity(e);
122
+ } else {
123
+ throw new Error(`Unrecognized request`, e.data.request);
124
+ }
125
+ }
126
+
127
+ // main() is called every time a new message comes in.
128
+ self.onmessage = main;
129
+
.history/copyslices.worker_20241204081958.js ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2024 The Google Research Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ /**
16
+ * Web worker responsible for copying bytes from sliced RGBA arrays to other
17
+ * targets.
18
+ */
19
+
20
+ importScripts("public/utils.js");
21
+
22
+ /**
23
+ * Copy asset.asset's contents into dstData using the format described by src &
24
+ * dst.
25
+ */
26
+ async function copySliceToBuffer(dstData, asset, src, dst) {
27
+ console.assert(src.channels.length == dst.channels.length, src, dst);
28
+
29
+ // Determine the offset for the output for this slice. Assume that each
30
+ // slice has the same shape.
31
+ let numPixels = product(asset.shape);
32
+ let baseOutOffset = numPixels * dst.format.numChannels * asset.sliceIndex;
33
+
34
+ // Wait for data to be ready.
35
+ let srcData = await asset.asset;
36
+
37
+ // Copy this asset's contents into dstData.
38
+ for (let px = 0; px < numPixels; ++px) {
39
+ // Buffer offsets for this pixel.
40
+ let inOffset = px * src.format.numChannels;
41
+ let outOffset = baseOutOffset + px * dst.format.numChannels;
42
+ for (let i = 0; i < src.channels.length; ++i) {
43
+ let inChannel = src.channels[i];
44
+ let outChannel = dst.channels[i];
45
+ dstData[outOffset + outChannel] = srcData[inOffset + inChannel];
46
+ }
47
+ }
48
+ }
49
+
50
+
51
+ /**
52
+ * Process an asset of type *_slices.
53
+ */
54
+ function processSlices(e) {
55
+ const i = e.data.i;
56
+ let { asset, src, dst } = e.data.request;
57
+
58
+ let numPixels = product(asset.shape);
59
+ let result = new Uint8Array(numPixels * dst.format.numChannels);
60
+
61
+ let promises = asset.sliceAssets.map((sliceAsset) => {
62
+ return copySliceToBuffer(result, sliceAsset, src, dst);
63
+ });
64
+
65
+ return Promise.all(promises).then(() => {
66
+ self.postMessage({i: i, result: result}, [result.buffer]);
67
+ });
68
+ }
69
+
70
+
71
+ /**
72
+ * Process sparse grid's density.
73
+ */
74
+ function processSparseGridDensity(e) {
75
+ const i = e.data.i;
76
+ let { asset } = e.data.request;
77
+
78
+ let numSlices = asset.rgbAndDensityAsset.numSlices;
79
+ console.assert(asset.rgbAndDensityAsset.numSlices == numSlices, asset);
80
+ console.assert(asset.featuresAsset.numSlices == numSlices, asset);
81
+
82
+ // Create a buffer for a luminance-alpha texture.
83
+ let result = new Uint8Array(product(asset.rgbAndDensityAsset.shape) * 2);
84
+
85
+ // Populate texture as assets arrive.
86
+ let promises = range(numSlices).map((i) => {
87
+ let rgbSliceAsset = asset.rgbAndDensityAsset.sliceAssets[i];
88
+ let featuresSliceAsset = asset.featuresAsset.sliceAssets[i];
89
+
90
+ // Copy density features to buffer. This requires merging the alpha values
91
+ // from two different data sources.
92
+ let copyLuminance = copySliceToBuffer(
93
+ result,
94
+ rgbSliceAsset,
95
+ GridTextureSource.ALPHA_FROM_RGBA,
96
+ GridTextureDestination.LUMINANCE_IN_LUMINANCE_ALPHA,
97
+ );
98
+
99
+ let copyAlpha = copySliceToBuffer(
100
+ result,
101
+ featuresSliceAsset,
102
+ GridTextureSource.ALPHA_FROM_RGBA,
103
+ GridTextureDestination.ALPHA_IN_LUMINANCE_ALPHA,
104
+ );
105
+
106
+ return Promise.all([copyLuminance, copyAlpha]);
107
+ });
108
+
109
+ return Promise.all(promises).then(() => {
110
+ self.postMessage({i: i, result: result}, [result.buffer]);
111
+ });
112
+ }
113
+
114
+ /**
115
+ * Main entry point.
116
+ */
117
+ function main(e) {
118
+ if (e.data.request.fn == 'mergeSlices') {
119
+ return processSlices(e);
120
+ } else if (e.data.request.fn == 'mergeSparseGridDensity') {
121
+ return processSparseGridDensity(e);
122
+ } else {
123
+ throw new Error(`Unrecognized request`, e.data.request);
124
+ }
125
+ }
126
+
127
+ // main() is called every time a new message comes in.
128
+ self.onmessage = main;
129
+
.history/copyslices.worker_20241204082633.js ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2024 The Google Research Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ /**
16
+ * Web worker responsible for copying bytes from sliced RGBA arrays to other
17
+ * targets.
18
+ */
19
+
20
+ importScripts("utils.js");
21
+
22
+ /**
23
+ * Copy asset.asset's contents into dstData using the format described by src &
24
+ * dst.
25
+ */
26
+ async function copySliceToBuffer(dstData, asset, src, dst) {
27
+ console.assert(src.channels.length == dst.channels.length, src, dst);
28
+
29
+ // Determine the offset for the output for this slice. Assume that each
30
+ // slice has the same shape.
31
+ let numPixels = product(asset.shape);
32
+ let baseOutOffset = numPixels * dst.format.numChannels * asset.sliceIndex;
33
+
34
+ // Wait for data to be ready.
35
+ let srcData = await asset.asset;
36
+
37
+ // Copy this asset's contents into dstData.
38
+ for (let px = 0; px < numPixels; ++px) {
39
+ // Buffer offsets for this pixel.
40
+ let inOffset = px * src.format.numChannels;
41
+ let outOffset = baseOutOffset + px * dst.format.numChannels;
42
+ for (let i = 0; i < src.channels.length; ++i) {
43
+ let inChannel = src.channels[i];
44
+ let outChannel = dst.channels[i];
45
+ dstData[outOffset + outChannel] = srcData[inOffset + inChannel];
46
+ }
47
+ }
48
+ }
49
+
50
+
51
+ /**
52
+ * Process an asset of type *_slices.
53
+ */
54
+ function processSlices(e) {
55
+ const i = e.data.i;
56
+ let { asset, src, dst } = e.data.request;
57
+
58
+ let numPixels = product(asset.shape);
59
+ let result = new Uint8Array(numPixels * dst.format.numChannels);
60
+
61
+ let promises = asset.sliceAssets.map((sliceAsset) => {
62
+ return copySliceToBuffer(result, sliceAsset, src, dst);
63
+ });
64
+
65
+ return Promise.all(promises).then(() => {
66
+ self.postMessage({i: i, result: result}, [result.buffer]);
67
+ });
68
+ }
69
+
70
+
71
+ /**
72
+ * Process sparse grid's density.
73
+ */
74
+ function processSparseGridDensity(e) {
75
+ const i = e.data.i;
76
+ let { asset } = e.data.request;
77
+
78
+ let numSlices = asset.rgbAndDensityAsset.numSlices;
79
+ console.assert(asset.rgbAndDensityAsset.numSlices == numSlices, asset);
80
+ console.assert(asset.featuresAsset.numSlices == numSlices, asset);
81
+
82
+ // Create a buffer for a luminance-alpha texture.
83
+ let result = new Uint8Array(product(asset.rgbAndDensityAsset.shape) * 2);
84
+
85
+ // Populate texture as assets arrive.
86
+ let promises = range(numSlices).map((i) => {
87
+ let rgbSliceAsset = asset.rgbAndDensityAsset.sliceAssets[i];
88
+ let featuresSliceAsset = asset.featuresAsset.sliceAssets[i];
89
+
90
+ // Copy density features to buffer. This requires merging the alpha values
91
+ // from two different data sources.
92
+ let copyLuminance = copySliceToBuffer(
93
+ result,
94
+ rgbSliceAsset,
95
+ GridTextureSource.ALPHA_FROM_RGBA,
96
+ GridTextureDestination.LUMINANCE_IN_LUMINANCE_ALPHA,
97
+ );
98
+
99
+ let copyAlpha = copySliceToBuffer(
100
+ result,
101
+ featuresSliceAsset,
102
+ GridTextureSource.ALPHA_FROM_RGBA,
103
+ GridTextureDestination.ALPHA_IN_LUMINANCE_ALPHA,
104
+ );
105
+
106
+ return Promise.all([copyLuminance, copyAlpha]);
107
+ });
108
+
109
+ return Promise.all(promises).then(() => {
110
+ self.postMessage({i: i, result: result}, [result.buffer]);
111
+ });
112
+ }
113
+
114
+ /**
115
+ * Main entry point.
116
+ */
117
+ function main(e) {
118
+ if (e.data.request.fn == 'mergeSlices') {
119
+ return processSlices(e);
120
+ } else if (e.data.request.fn == 'mergeSparseGridDensity') {
121
+ return processSparseGridDensity(e);
122
+ } else {
123
+ throw new Error(`Unrecognized request`, e.data.request);
124
+ }
125
+ }
126
+
127
+ // main() is called every time a new message comes in.
128
+ self.onmessage = main;
129
+
.history/copyslices.worker_20241204114216.js ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2024 The Google Research Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ /**
16
+ * Web worker responsible for copying bytes from sliced RGBA arrays to other
17
+ * targets.
18
+ */
19
+
20
+ importScripts("/utils.js");
21
+
22
+ /**
23
+ * Copy asset.asset's contents into dstData using the format described by src &
24
+ * dst.
25
+ */
26
+ async function copySliceToBuffer(dstData, asset, src, dst) {
27
+ console.assert(src.channels.length == dst.channels.length, src, dst);
28
+
29
+ // Determine the offset for the output for this slice. Assume that each
30
+ // slice has the same shape.
31
+ let numPixels = product(asset.shape);
32
+ let baseOutOffset = numPixels * dst.format.numChannels * asset.sliceIndex;
33
+
34
+ // Wait for data to be ready.
35
+ let srcData = await asset.asset;
36
+
37
+ // Copy this asset's contents into dstData.
38
+ for (let px = 0; px < numPixels; ++px) {
39
+ // Buffer offsets for this pixel.
40
+ let inOffset = px * src.format.numChannels;
41
+ let outOffset = baseOutOffset + px * dst.format.numChannels;
42
+ for (let i = 0; i < src.channels.length; ++i) {
43
+ let inChannel = src.channels[i];
44
+ let outChannel = dst.channels[i];
45
+ dstData[outOffset + outChannel] = srcData[inOffset + inChannel];
46
+ }
47
+ }
48
+ }
49
+
50
+
51
+ /**
52
+ * Process an asset of type *_slices.
53
+ */
54
+ function processSlices(e) {
55
+ const i = e.data.i;
56
+ let { asset, src, dst } = e.data.request;
57
+
58
+ let numPixels = product(asset.shape);
59
+ let result = new Uint8Array(numPixels * dst.format.numChannels);
60
+
61
+ let promises = asset.sliceAssets.map((sliceAsset) => {
62
+ return copySliceToBuffer(result, sliceAsset, src, dst);
63
+ });
64
+
65
+ return Promise.all(promises).then(() => {
66
+ self.postMessage({i: i, result: result}, [result.buffer]);
67
+ });
68
+ }
69
+
70
+
71
+ /**
72
+ * Process sparse grid's density.
73
+ */
74
+ function processSparseGridDensity(e) {
75
+ const i = e.data.i;
76
+ let { asset } = e.data.request;
77
+
78
+ let numSlices = asset.rgbAndDensityAsset.numSlices;
79
+ console.assert(asset.rgbAndDensityAsset.numSlices == numSlices, asset);
80
+ console.assert(asset.featuresAsset.numSlices == numSlices, asset);
81
+
82
+ // Create a buffer for a luminance-alpha texture.
83
+ let result = new Uint8Array(product(asset.rgbAndDensityAsset.shape) * 2);
84
+
85
+ // Populate texture as assets arrive.
86
+ let promises = range(numSlices).map((i) => {
87
+ let rgbSliceAsset = asset.rgbAndDensityAsset.sliceAssets[i];
88
+ let featuresSliceAsset = asset.featuresAsset.sliceAssets[i];
89
+
90
+ // Copy density features to buffer. This requires merging the alpha values
91
+ // from two different data sources.
92
+ let copyLuminance = copySliceToBuffer(
93
+ result,
94
+ rgbSliceAsset,
95
+ GridTextureSource.ALPHA_FROM_RGBA,
96
+ GridTextureDestination.LUMINANCE_IN_LUMINANCE_ALPHA,
97
+ );
98
+
99
+ let copyAlpha = copySliceToBuffer(
100
+ result,
101
+ featuresSliceAsset,
102
+ GridTextureSource.ALPHA_FROM_RGBA,
103
+ GridTextureDestination.ALPHA_IN_LUMINANCE_ALPHA,
104
+ );
105
+
106
+ return Promise.all([copyLuminance, copyAlpha]);
107
+ });
108
+
109
+ return Promise.all(promises).then(() => {
110
+ self.postMessage({i: i, result: result}, [result.buffer]);
111
+ });
112
+ }
113
+
114
+ /**
115
+ * Main entry point.
116
+ */
117
+ function main(e) {
118
+ if (e.data.request.fn == 'mergeSlices') {
119
+ return processSlices(e);
120
+ } else if (e.data.request.fn == 'mergeSparseGridDensity') {
121
+ return processSparseGridDensity(e);
122
+ } else {
123
+ throw new Error(`Unrecognized request`, e.data.request);
124
+ }
125
+ }
126
+
127
+ // main() is called every time a new message comes in.
128
+ self.onmessage = main;
129
+
.history/copyslices.worker_20241204114218.js ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2024 The Google Research Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ /**
16
+ * Web worker responsible for copying bytes from sliced RGBA arrays to other
17
+ * targets.
18
+ */
19
+
20
+ importScripts("utils.js");
21
+
22
+ /**
23
+ * Copy asset.asset's contents into dstData using the format described by src &
24
+ * dst.
25
+ */
26
+ async function copySliceToBuffer(dstData, asset, src, dst) {
27
+ console.assert(src.channels.length == dst.channels.length, src, dst);
28
+
29
+ // Determine the offset for the output for this slice. Assume that each
30
+ // slice has the same shape.
31
+ let numPixels = product(asset.shape);
32
+ let baseOutOffset = numPixels * dst.format.numChannels * asset.sliceIndex;
33
+
34
+ // Wait for data to be ready.
35
+ let srcData = await asset.asset;
36
+
37
+ // Copy this asset's contents into dstData.
38
+ for (let px = 0; px < numPixels; ++px) {
39
+ // Buffer offsets for this pixel.
40
+ let inOffset = px * src.format.numChannels;
41
+ let outOffset = baseOutOffset + px * dst.format.numChannels;
42
+ for (let i = 0; i < src.channels.length; ++i) {
43
+ let inChannel = src.channels[i];
44
+ let outChannel = dst.channels[i];
45
+ dstData[outOffset + outChannel] = srcData[inOffset + inChannel];
46
+ }
47
+ }
48
+ }
49
+
50
+
51
+ /**
52
+ * Process an asset of type *_slices.
53
+ */
54
+ function processSlices(e) {
55
+ const i = e.data.i;
56
+ let { asset, src, dst } = e.data.request;
57
+
58
+ let numPixels = product(asset.shape);
59
+ let result = new Uint8Array(numPixels * dst.format.numChannels);
60
+
61
+ let promises = asset.sliceAssets.map((sliceAsset) => {
62
+ return copySliceToBuffer(result, sliceAsset, src, dst);
63
+ });
64
+
65
+ return Promise.all(promises).then(() => {
66
+ self.postMessage({i: i, result: result}, [result.buffer]);
67
+ });
68
+ }
69
+
70
+
71
+ /**
72
+ * Process sparse grid's density.
73
+ */
74
+ function processSparseGridDensity(e) {
75
+ const i = e.data.i;
76
+ let { asset } = e.data.request;
77
+
78
+ let numSlices = asset.rgbAndDensityAsset.numSlices;
79
+ console.assert(asset.rgbAndDensityAsset.numSlices == numSlices, asset);
80
+ console.assert(asset.featuresAsset.numSlices == numSlices, asset);
81
+
82
+ // Create a buffer for a luminance-alpha texture.
83
+ let result = new Uint8Array(product(asset.rgbAndDensityAsset.shape) * 2);
84
+
85
+ // Populate texture as assets arrive.
86
+ let promises = range(numSlices).map((i) => {
87
+ let rgbSliceAsset = asset.rgbAndDensityAsset.sliceAssets[i];
88
+ let featuresSliceAsset = asset.featuresAsset.sliceAssets[i];
89
+
90
+ // Copy density features to buffer. This requires merging the alpha values
91
+ // from two different data sources.
92
+ let copyLuminance = copySliceToBuffer(
93
+ result,
94
+ rgbSliceAsset,
95
+ GridTextureSource.ALPHA_FROM_RGBA,
96
+ GridTextureDestination.LUMINANCE_IN_LUMINANCE_ALPHA,
97
+ );
98
+
99
+ let copyAlpha = copySliceToBuffer(
100
+ result,
101
+ featuresSliceAsset,
102
+ GridTextureSource.ALPHA_FROM_RGBA,
103
+ GridTextureDestination.ALPHA_IN_LUMINANCE_ALPHA,
104
+ );
105
+
106
+ return Promise.all([copyLuminance, copyAlpha]);
107
+ });
108
+
109
+ return Promise.all(promises).then(() => {
110
+ self.postMessage({i: i, result: result}, [result.buffer]);
111
+ });
112
+ }
113
+
114
+ /**
115
+ * Main entry point.
116
+ */
117
+ function main(e) {
118
+ if (e.data.request.fn == 'mergeSlices') {
119
+ return processSlices(e);
120
+ } else if (e.data.request.fn == 'mergeSparseGridDensity') {
121
+ return processSparseGridDensity(e);
122
+ } else {
123
+ throw new Error(`Unrecognized request`, e.data.request);
124
+ }
125
+ }
126
+
127
+ // main() is called every time a new message comes in.
128
+ self.onmessage = main;
129
+
.history/fetch_ex_bbox_20241120090937.js ADDED
File without changes
.history/fetch_ex_bbox_20241120090941.js ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ function setupCameraRestriction(gCamera, gRenderer, gSphereScene) {
2
+ const polygonVertices = [
3
+ new THREE.Vector2(-0.25, -0.25),
4
+ new THREE.Vector2(-0.25, 0.15),
5
+ new THREE.Vector2(0.0, 0.15),
6
+ new THREE.Vector2(0.0, 0.25),
7
+ new THREE.Vector2(0.25, 0.25),
8
+ new THREE.Vector2(0.25, 0.0),
9
+ new THREE.Vector2(0.15, 0.0),
10
+ new THREE.Vector2(0.15, -0.25),
11
+ // Ajoutez d'autres points pour définir votre forme de "L"
12
+ ];
13
+
14
+ const fixedHeight = 0.5; // Hauteur fixe sur l'axe y
15
+
16
+ // Fonction pour créer une visualisation du polygone
17
+ function createPolygonVisualization() {
18
+ const material = new THREE.LineBasicMaterial({ color: 0x00ff00 });
19
+ const points = [];
20
+
21
+ // Ajouter chaque sommet comme un point 3D (x, fixedHeight, z)
22
+ polygonVertices.forEach(vertex => {
23
+ points.push(new THREE.Vector3(vertex.x, fixedHeight, vertex.y));
24
+ });
25
+
26
+ // Ajouter le premier point à la fin pour fermer le polygone
27
+ points.push(new THREE.Vector3(polygonVertices[0].x, fixedHeight, polygonVertices[0].y));
28
+
29
+ // Créer une géométrie de ligne avec les points
30
+ const geometry = new THREE.BufferGeometry().setFromPoints(points);
31
+ const line = new THREE.Line(geometry, material);
32
+ gSphereScene.add(line);
33
+
34
+ // Ajouter des sphères aux sommets pour marquer les points
35
+ const sphereGeometry = new THREE.SphereGeometry(0.01, 16, 16);
36
+ const sphereMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
37
+ polygonVertices.forEach(vertex => {
38
+ const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
39
+ sphere.position.set(vertex.x, fixedHeight, vertex.y);
40
+ gSphereScene.add(sphere);
41
+ });
42
+ }
43
+
44
+ // Appeler la fonction pour créer la visualisation du polygone
45
+ createPolygonVisualization();
46
+
47
+ // Fonction pour vérifier si un point est dans le polygone en utilisant Ray Casting
48
+ function isPointInPolygon(point, vertices) {
49
+ let intersects = 0;
50
+ for (let i = 0; i < vertices.length; i++) {
51
+ const v1 = vertices[i];
52
+ const v2 = vertices[(i + 1) % vertices.length];
53
+
54
+ if ((v1.y > point.y) !== (v2.y > point.y) &&
55
+ point.x < ((v2.x - v1.x) * (point.y - v1.y)) / (v2.y - v1.y) + v1.x) {
56
+ intersects++;
57
+ }
58
+ }
59
+ return intersects % 2 === 1;
60
+ }
61
+
62
+ function restrictCameraPosition() {
63
+ gCamera.position.y = fixedHeight;
64
+
65
+ const cameraPos2D = new THREE.Vector2(gCamera.position.x, gCamera.position.z);
66
+
67
+ if (!isPointInPolygon(cameraPos2D, polygonVertices)) {
68
+ let closestPoint = cameraPos2D;
69
+ let minDistance = Infinity;
70
+
71
+ for (let i = 0; i < polygonVertices.length; i++) {
72
+ const v1 = polygonVertices[i];
73
+ const v2 = polygonVertices[(i + 1) % polygonVertices.length];
74
+
75
+ const closestPointOnEdge = closestPointOnLineSegment(cameraPos2D, v1, v2);
76
+ const distance = cameraPos2D.distanceTo(closestPointOnEdge);
77
+
78
+ if (distance < minDistance) {
79
+ minDistance = distance;
80
+ closestPoint = closestPointOnEdge;
81
+ }
82
+ }
83
+
84
+ gCamera.position.x = closestPoint.x;
85
+ gCamera.position.z = closestPoint.y;
86
+ }
87
+ }
88
+
89
+ function closestPointOnLineSegment(point, v1, v2) {
90
+ const lineVec = new THREE.Vector2().subVectors(v2, v1);
91
+ const pointVec = new THREE.Vector2().subVectors(point, v1);
92
+ const lineLen = lineVec.length();
93
+ const lineUnitVec = lineVec.normalize();
94
+ const projection = pointVec.dot(lineUnitVec);
95
+ const t = Math.max(0, Math.min(lineLen, projection));
96
+ return new THREE.Vector2().copy(v1).add(lineUnitVec.multiplyScalar(t));
97
+ }
98
+
99
+ function animate() {
100
+ requestAnimationFrame(animate);
101
+
102
+ restrictCameraPosition();
103
+ gRenderer.render(gSphereScene, gCamera);
104
+ }
105
+
106
+ animate();
107
+ }
108
+
.history/fetch_ex_bbox_20241120093705.js ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ /**
3
+ * Fetch bounding box data from a JSON file in the specified directory.
4
+ * @param {string} dirUrl - The directory URL where the boundingBox.json is located.
5
+ * @returns {Promise<Array<THREE.Vector2>>} - Returns a promise resolving to an array of 2D vectors.
6
+ */
7
+ async function fetchBoundingBox(dirUrl) {
8
+ try {
9
+ // Extract the base directory by removing everything after the last "/"
10
+ const baseDir = dirUrl.split('/')[0];
11
+
12
+ // Construct the full path for the boundingBox.json
13
+ const boundingBoxPath = `${baseDir}/boundingBox.json`;
14
+
15
+ // Use the loadJSONFile function to fetch the bounding box
16
+ const jsonData = await loadJSONFile(boundingBoxPath);
17
+
18
+ // Extract the sphere positions from the boundingBox data
19
+ const spheres = jsonData.boundingBox.spheres || [];
20
+ const vertices = spheres.map(sphere => new THREE.Vector2(sphere.x, sphere.z));
21
+
22
+ return vertices;
23
+ } catch (error) {
24
+ console.error('Erreur lors de la récupération des données de la bounding box :', error);
25
+ throw error;
26
+ }
27
+ }
28
+
29
+ /**
30
+ * Sets up camera restriction using bounding box data.
31
+ * @param {THREE.Camera} gCamera - The camera to restrict.
32
+ * @param {THREE.Renderer} gRenderer - The renderer for rendering the scene.
33
+ * @param {THREE.Scene} gRayMarchScene - The scene to which restrictions are applied.
34
+ * @param {string} dirUrl - The directory URL where the boundingBox.json is located.
35
+ */
36
+ async function setupCameraRestriction(gCamera, gRenderer, gRayMarchScene, dirUrl) {
37
+ const fixedHeight = 0.5; // Fixed y-coordinate for the camera
38
+
39
+ // Fetch the bounding box data
40
+ const polygonVertices = await fetchBoundingBox(dirUrl);
41
+
42
+ // Visualize the bounding box in the scene
43
+ function createPolygonVisualization() {
44
+ const material = new THREE.LineBasicMaterial({ color: 0x00ff00 });
45
+ const points = [];
46
+
47
+ // Convert 2D points to 3D for visualization
48
+ polygonVertices.forEach(vertex => {
49
+ points.push(new THREE.Vector3(vertex.x, fixedHeight, vertex.y));
50
+ });
51
+
52
+ // Close the polygon by adding the first point to the end
53
+ points.push(new THREE.Vector3(polygonVertices[0].x, fixedHeight, polygonVertices[0].y));
54
+
55
+ // Create a line geometry for visualization
56
+ const geometry = new THREE.BufferGeometry().setFromPoints(points);
57
+ const line = new THREE.Line(geometry, material);
58
+ gRayMarchScene.add(line);
59
+
60
+ // Add spheres to mark the vertices
61
+ const sphereGeometry = new THREE.SphereGeometry(0.01, 16, 16);
62
+ const sphereMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
63
+ polygonVertices.forEach(vertex => {
64
+ const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
65
+ sphere.position.set(vertex.x, fixedHeight, vertex.y);
66
+ gRayMarchScene.add(sphere);
67
+ });
68
+ }
69
+
70
+ createPolygonVisualization();
71
+
72
+ // Check if a point is inside the polygon
73
+ function isPointInPolygon(point, vertices) {
74
+ let intersects = 0;
75
+ for (let i = 0; i < vertices.length; i++) {
76
+ const v1 = vertices[i];
77
+ const v2 = vertices[(i + 1) % vertices.length];
78
+
79
+ if ((v1.y > point.y) !== (v2.y > point.y) &&
80
+ point.x < ((v2.x - v1.x) * (point.y - v1.y)) / (v2.y - v1.y) + v1.x) {
81
+ intersects++;
82
+ }
83
+ }
84
+ return intersects % 2 === 1;
85
+ }
86
+
87
+ // Restrict camera position based on bounding box
88
+ function restrictCameraPosition() {
89
+ gCamera.position.y = fixedHeight;
90
+
91
+ const cameraPos2D = new THREE.Vector2(gCamera.position.x, gCamera.position.z);
92
+
93
+ if (!isPointInPolygon(cameraPos2D, polygonVertices)) {
94
+ let closestPoint = cameraPos2D;
95
+ let minDistance = Infinity;
96
+
97
+ for (let i = 0; i < polygonVertices.length; i++) {
98
+ const v1 = polygonVertices[i];
99
+ const v2 = polygonVertices[(i + 1) % polygonVertices.length];
100
+
101
+ const closestPointOnEdge = closestPointOnLineSegment(cameraPos2D, v1, v2);
102
+ const distance = cameraPos2D.distanceTo(closestPointOnEdge);
103
+
104
+ if (distance < minDistance) {
105
+ minDistance = distance;
106
+ closestPoint = closestPointOnEdge;
107
+ }
108
+ }
109
+
110
+ gCamera.position.x = closestPoint.x;
111
+ gCamera.position.z = closestPoint.y;
112
+ }
113
+ }
114
+
115
+ function closestPointOnLineSegment(point, v1, v2) {
116
+ const lineVec = new THREE.Vector2().subVectors(v2, v1);
117
+ const pointVec = new THREE.Vector2().subVectors(point, v1);
118
+ const lineLen = lineVec.length();
119
+ const lineUnitVec = lineVec.normalize();
120
+ const projection = pointVec.dot(lineUnitVec);
121
+ const t = Math.max(0, Math.min(lineLen, projection));
122
+ return new THREE.Vector2().copy(v1).add(lineUnitVec.multiplyScalar(t));
123
+ }
124
+
125
+ function animate() {
126
+ requestAnimationFrame(animate);
127
+
128
+ restrictCameraPosition();
129
+ gRenderer.render(gRayMarchScene, gCamera);
130
+ }
131
+
132
+ animate();
133
+ }
.history/fetch_ex_bbox_20241120093930.js ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ /**
3
+ * Fetch bounding box data from a JSON file in the specified directory.
4
+ * @param {string} dirUrl - The directory URL where the boundingBox.json is located.
5
+ * @returns {Promise<Array<THREE.Vector2>>} - Returns a promise resolving to an array of 2D vectors.
6
+ */
7
+ async function fetchBoundingBox(dirUrl) {
8
+ try {
9
+ // Extract the base directory by removing everything after the last "/"
10
+ const baseDir = dirUrl.split('/')[0];
11
+
12
+ // Construct the full path for the boundingBox.json
13
+ const boundingBoxPath = `${baseDir}/boundingBox.json`;
14
+
15
+ // Use the loadJSONFile function to fetch the bounding box
16
+ const jsonData = await loadJSONFile(boundingBoxPath);
17
+
18
+ // Extract the sphere positions from the boundingBox data
19
+ const spheres = jsonData.boundingBox.spheres || [];
20
+ const vertices = spheres.map(sphere => new THREE.Vector2(sphere.x, sphere.z));
21
+
22
+ // Assume all spheres have the same `y` value, extract it
23
+ const fixedHeight = spheres.length > 0 ? spheres[0].y : 0;
24
+
25
+ return { vertices, fixedHeight };
26
+ } catch (error) {
27
+ console.error('Erreur lors de la récupération des données de la bounding box :', error);
28
+ throw error;
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Sets up camera restriction using bounding box data.
34
+ * @param {THREE.Camera} gCamera - The camera to restrict.
35
+ * @param {THREE.Renderer} gRenderer - The renderer for rendering the scene.
36
+ * @param {THREE.Scene} gRayMarchScene - The scene to which restrictions are applied.
37
+ * @param {string} dirUrl - The directory URL where the boundingBox.json is located.
38
+ */
39
+ async function setupCameraRestriction(gCamera, gRenderer, gRayMarchScene, dirUrl) {
40
+ const fixedHeight = 0.5; // Fixed y-coordinate for the camera
41
+
42
+ // Fetch the bounding box data
43
+ const polygonVertices = await fetchBoundingBox(dirUrl);
44
+
45
+ // Visualize the bounding box in the scene
46
+ function createPolygonVisualization() {
47
+ const material = new THREE.LineBasicMaterial({ color: 0x00ff00 });
48
+ const points = [];
49
+
50
+ // Convert 2D points to 3D for visualization
51
+ polygonVertices.forEach(vertex => {
52
+ points.push(new THREE.Vector3(vertex.x, fixedHeight, vertex.y));
53
+ });
54
+
55
+ // Close the polygon by adding the first point to the end
56
+ points.push(new THREE.Vector3(polygonVertices[0].x, fixedHeight, polygonVertices[0].y));
57
+
58
+ // Create a line geometry for visualization
59
+ const geometry = new THREE.BufferGeometry().setFromPoints(points);
60
+ const line = new THREE.Line(geometry, material);
61
+ gRayMarchScene.add(line);
62
+
63
+ // Add spheres to mark the vertices
64
+ const sphereGeometry = new THREE.SphereGeometry(0.01, 16, 16);
65
+ const sphereMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
66
+ polygonVertices.forEach(vertex => {
67
+ const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
68
+ sphere.position.set(vertex.x, fixedHeight, vertex.y);
69
+ gRayMarchScene.add(sphere);
70
+ });
71
+ }
72
+
73
+ createPolygonVisualization();
74
+
75
+ // Check if a point is inside the polygon
76
+ function isPointInPolygon(point, vertices) {
77
+ let intersects = 0;
78
+ for (let i = 0; i < vertices.length; i++) {
79
+ const v1 = vertices[i];
80
+ const v2 = vertices[(i + 1) % vertices.length];
81
+
82
+ if ((v1.y > point.y) !== (v2.y > point.y) &&
83
+ point.x < ((v2.x - v1.x) * (point.y - v1.y)) / (v2.y - v1.y) + v1.x) {
84
+ intersects++;
85
+ }
86
+ }
87
+ return intersects % 2 === 1;
88
+ }
89
+
90
+ // Restrict camera position based on bounding box
91
+ function restrictCameraPosition() {
92
+ gCamera.position.y = fixedHeight;
93
+
94
+ const cameraPos2D = new THREE.Vector2(gCamera.position.x, gCamera.position.z);
95
+
96
+ if (!isPointInPolygon(cameraPos2D, polygonVertices)) {
97
+ let closestPoint = cameraPos2D;
98
+ let minDistance = Infinity;
99
+
100
+ for (let i = 0; i < polygonVertices.length; i++) {
101
+ const v1 = polygonVertices[i];
102
+ const v2 = polygonVertices[(i + 1) % polygonVertices.length];
103
+
104
+ const closestPointOnEdge = closestPointOnLineSegment(cameraPos2D, v1, v2);
105
+ const distance = cameraPos2D.distanceTo(closestPointOnEdge);
106
+
107
+ if (distance < minDistance) {
108
+ minDistance = distance;
109
+ closestPoint = closestPointOnEdge;
110
+ }
111
+ }
112
+
113
+ gCamera.position.x = closestPoint.x;
114
+ gCamera.position.z = closestPoint.y;
115
+ }
116
+ }
117
+
118
+ function closestPointOnLineSegment(point, v1, v2) {
119
+ const lineVec = new THREE.Vector2().subVectors(v2, v1);
120
+ const pointVec = new THREE.Vector2().subVectors(point, v1);
121
+ const lineLen = lineVec.length();
122
+ const lineUnitVec = lineVec.normalize();
123
+ const projection = pointVec.dot(lineUnitVec);
124
+ const t = Math.max(0, Math.min(lineLen, projection));
125
+ return new THREE.Vector2().copy(v1).add(lineUnitVec.multiplyScalar(t));
126
+ }
127
+
128
+ function animate() {
129
+ requestAnimationFrame(animate);
130
+
131
+ restrictCameraPosition();
132
+ gRenderer.render(gRayMarchScene, gCamera);
133
+ }
134
+
135
+ animate();
136
+ }
.history/form/index_20241119001656.html ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Créer une visite</title>
7
+ <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
9
+ <link href="../../../../dist/tailwind.css" rel="stylesheet">
10
+ </head>
11
+ <body class="bg-bg text-textDark font-sans">
12
+ <!-- Conteneur principal -->
13
+ <div id="dashboard-layout" class="flex">
14
+ <div id="content" class="flex-1 p-6">
15
+ <h1 class="text-2xl font-bold mb-6">Créer votre visite virtuelle simplement !</h1>
16
+ <div id="form-and-preview-container" class="flex gap-6">
17
+ <!-- Formulaire -->
18
+ <div id="form-container" class="bg-white p-6 rounded-lg shadow-md flex-1">
19
+ <form id="property-form" class="space-y-4">
20
+ <div class="form-group">
21
+ <label for="visitName" class="block font-semibold">Nom de la visite :</label>
22
+ <input type="text" id="visitName" name="visitName" placeholder="Entrez le nom de la visite"
23
+ class="w-full border rounded px-4 py-2">
24
+ </div>
25
+ <div class="form-group">
26
+ <label for="propertyDescription" class="block font-semibold">Description du bien :</label>
27
+ <textarea id="propertyDescription" name="propertyDescription" rows="4"
28
+ placeholder="Entrez une description du bien"
29
+ class="w-full border rounded px-4 py-2"></textarea>
30
+ </div>
31
+ <div class="form-group">
32
+ <label for="propertyAddress" class="block font-semibold">Adresse du bien :</label>
33
+ <input type="text" id="propertyAddress" name="propertyAddress" placeholder="Entrez l'adresse"
34
+ class="w-full border rounded px-4 py-2">
35
+ </div>
36
+ <div class="form-group">
37
+ <label for="propertyOwner" class="block font-semibold">Propriétaire du bien :</label>
38
+ <input type="text" id="propertyOwner" name="propertyOwner" placeholder="Entrez le nom du propriétaire"
39
+ class="w-full border rounded px-4 py-2">
40
+ </div>
41
+ <div class="form-group">
42
+ <label for="propertyPrice" class="block font-semibold">Prix du bien :</label>
43
+ <input type="number" id="propertyPrice" name="propertyPrice" placeholder="Entrez le prix"
44
+ class="w-full border rounded px-4 py-2">
45
+ </div>
46
+ <input type="file" id="input-media-hidden" class="hidden"
47
+ onchange="previewMedia(this)"
48
+ accept="image/jpeg, image/png, video/mp4, video/webm" multiple>
49
+ <button type="button" class="bg-secondary text-white px-4 py-2 rounded"
50
+ onclick="HandleBrowseClick('input-media-hidden');">UPLOAD MEDIA</button>
51
+ <button type="submit" id="validateButton" class="bg-blue-600 text-white px-4 py-2 rounded">VALIDER</button>
52
+ </form>
53
+ </div>
54
+ <!-- Prévisualisation -->
55
+ <div id="media-preview-container" class="flex-1">
56
+ <h2 class="text-xl font-bold mb-4">Prévisualisation des médias</h2>
57
+ <div class="border rounded-lg p-4 bg-white shadow-sm">
58
+ <!-- Aperçus des images et vidéos -->
59
+ </div>
60
+ </div>
61
+ </div>
62
+ </div>
63
+ </div>
64
+
65
+ <!-- Scripts principaux -->
66
+ <script src="/js/layout.js"></script>
67
+ <script src="/js/sidebar.js"></script>
68
+ <script src="/js/topbar.js"></script>
69
+ <script src="media_vu.js"></script>
70
+ </body>
71
+ </html>
.history/form/index_20241120180531.html ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Créer une visite</title>
7
+ <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
9
+ <link href="../../../../dist/tailwind.css" rel="stylesheet">
10
+ </head>
11
+ <body class="bg-bg text-textDark font-sans">
12
+ <!-- Conteneur principal -->
13
+ <div id="dashboard-layout" class="flex">
14
+ <div id="content" class="flex-1 p-6">
15
+ <h1 class="text-2xl font-bold mb-6">Créer votre visite virtuelle simplement !</h1>
16
+ <div id="form-and-preview-container" class="flex gap-6">
17
+ <!-- Formulaire -->
18
+ <div id="form-container" class="bg-white p-6 rounded-lg shadow-md flex-1">
19
+ <form id="property-form" class="space-y-4">
20
+ <div class="form-group">
21
+ <label for="visitName" class="block font-semibold">Nom de la visite :</label>
22
+ <input type="text" id="visitName" name="visitName" placeholder="Entrez le nom de la visite"
23
+ class="w-full border rounded px-4 py-2">
24
+ </div>
25
+ <div class="form-group">
26
+ <label for="propertyDescription" class="block font-semibold">Description du bien :</label>
27
+ <textarea id="propertyDescription" name="propertyDescription" rows="4"
28
+ placeholder="Entrez une description du bien"
29
+ class="w-full border rounded px-4 py-2"></textarea>
30
+ </div>
31
+ <div class="form-group">
32
+ <label for="propertyAddress" class="block font-semibold">Adresse du bien :</label>
33
+ <input type="text" id="propertyAddress" name="propertyAddress" placeholder="Entrez l'adresse"
34
+ class="w-full border rounded px-4 py-2">
35
+ </div>
36
+ <div class="form-group">
37
+ <label for="propertyOwner" class="block font-semibold">Propriétaire du bien :</label>
38
+ <input type="text" id="propertyOwner" name="propertyOwner" placeholder="Entrez le nom du propriétaire"
39
+ class="w-full border rounded px-4 py-2">
40
+ </div>
41
+ <div class="form-group">
42
+ <label for="propertyPrice" class="block font-semibold">Prix du bien :</label>
43
+ <input type="number" id="propertyPrice" name="propertyPrice" placeholder="Entrez le prix"
44
+ class="w-full border rounded px-4 py-2">
45
+ </div>
46
+ <input type="file" id="input-media-hidden" class="hidden"
47
+ onchange="previewMedia(this)"
48
+ accept="image/jpeg, image/png, video/mp4, video/webm" multiple>
49
+ <button type="button" class="bg-secondary text-white px-4 py-2 rounded"
50
+ onclick="HandleBrowseClick('input-media-hidden');">UPLOAD MEDIA</button>
51
+ <button type="submit" id="validateButton" class="bg-blue-600 text-white px-4 py-2 rounded">VALIDER</button>
52
+ </form>
53
+ </div>
54
+ <!-- Prévisualisation -->
55
+ <div id="media-preview-container" class="flex-1">
56
+ <h2 class="text-xl font-bold mb-4">Prévisualisation des médias</h2>
57
+ <div class="border rounded-lg p-4 bg-white shadow-sm">
58
+ <!-- Aperçus des images et vidéos -->
59
+ </div>
60
+ </div>
61
+ </div>
62
+ </div>
63
+ </div>
64
+
65
+ <script src="media_vu.js"></script>
66
+ </body>
67
+ </html>
.history/form/index_20241120180543.html ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Créer une visite</title>
7
+ <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
9
+ </head>
10
+ <body class="bg-bg text-textDark font-sans">
11
+ <!-- Conteneur principal -->
12
+ <div id="dashboard-layout" class="flex">
13
+ <div id="content" class="flex-1 p-6">
14
+ <h1 class="text-2xl font-bold mb-6">Créer votre visite virtuelle simplement !</h1>
15
+ <div id="form-and-preview-container" class="flex gap-6">
16
+ <!-- Formulaire -->
17
+ <div id="form-container" class="bg-white p-6 rounded-lg shadow-md flex-1">
18
+ <form id="property-form" class="space-y-4">
19
+ <div class="form-group">
20
+ <label for="visitName" class="block font-semibold">Nom de la visite :</label>
21
+ <input type="text" id="visitName" name="visitName" placeholder="Entrez le nom de la visite"
22
+ class="w-full border rounded px-4 py-2">
23
+ </div>
24
+ <div class="form-group">
25
+ <label for="propertyDescription" class="block font-semibold">Description du bien :</label>
26
+ <textarea id="propertyDescription" name="propertyDescription" rows="4"
27
+ placeholder="Entrez une description du bien"
28
+ class="w-full border rounded px-4 py-2"></textarea>
29
+ </div>
30
+ <div class="form-group">
31
+ <label for="propertyAddress" class="block font-semibold">Adresse du bien :</label>
32
+ <input type="text" id="propertyAddress" name="propertyAddress" placeholder="Entrez l'adresse"
33
+ class="w-full border rounded px-4 py-2">
34
+ </div>
35
+ <div class="form-group">
36
+ <label for="propertyOwner" class="block font-semibold">Propriétaire du bien :</label>
37
+ <input type="text" id="propertyOwner" name="propertyOwner" placeholder="Entrez le nom du propriétaire"
38
+ class="w-full border rounded px-4 py-2">
39
+ </div>
40
+ <div class="form-group">
41
+ <label for="propertyPrice" class="block font-semibold">Prix du bien :</label>
42
+ <input type="number" id="propertyPrice" name="propertyPrice" placeholder="Entrez le prix"
43
+ class="w-full border rounded px-4 py-2">
44
+ </div>
45
+ <input type="file" id="input-media-hidden" class="hidden"
46
+ onchange="previewMedia(this)"
47
+ accept="image/jpeg, image/png, video/mp4, video/webm" multiple>
48
+ <button type="button" class="bg-secondary text-white px-4 py-2 rounded"
49
+ onclick="HandleBrowseClick('input-media-hidden');">UPLOAD MEDIA</button>
50
+ <button type="submit" id="validateButton" class="bg-blue-600 text-white px-4 py-2 rounded">VALIDER</button>
51
+ </form>
52
+ </div>
53
+ <!-- Prévisualisation -->
54
+ <div id="media-preview-container" class="flex-1">
55
+ <h2 class="text-xl font-bold mb-4">Prévisualisation des médias</h2>
56
+ <div class="border rounded-lg p-4 bg-white shadow-sm">
57
+ <!-- Aperçus des images et vidéos -->
58
+ </div>
59
+ </div>
60
+ </div>
61
+ </div>
62
+ </div>
63
+
64
+ <script src="media_vu.js"></script>
65
+ </body>
66
+ </html>
.history/globals_20241204111341.js ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2024 The Google Research Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ /**
16
+ * @fileoverview Global state of the web viewer.
17
+ */
18
+
19
+ /**
20
+ * Our framerate display.
21
+ * @type {?Object}
22
+ */
23
+ let gStats = null;
24
+
25
+ /**
26
+ * If enabled, expect multiple submodels.
27
+ */
28
+ let gUseSubmodel = false;
29
+
30
+ /**
31
+ * Transform from world coordinates to the current submodel.
32
+ */
33
+ let gSubmodelTransform = null;
34
+
35
+ /**
36
+ * Deferred MLP parameters for the current submodel.
37
+ */
38
+ let gDeferredMlp = null;
39
+
40
+ /**
41
+ * Different display modes for debugging rendering.
42
+ * @enum {number}
43
+ */
44
+ const DisplayModeType = {
45
+ /** Runs the full model with view dependence. */
46
+ DISPLAY_NORMAL: 0,
47
+ /** Disables the view-dependence network. */
48
+ DISPLAY_DIFFUSE: 1,
49
+ /** Only shows the latent features. */
50
+ DISPLAY_FEATURES: 2,
51
+ /** Only shows the view dependent component. */
52
+ DISPLAY_VIEW_DEPENDENT: 3,
53
+ /** Only shows the coarse block grid. */
54
+ DISPLAY_COARSE_GRID: 4,
55
+ };
56
+
57
+ /** @type {!DisplayModeType} */
58
+ let gDisplayMode = DisplayModeType.DISPLAY_NORMAL;
59
+
60
+ /**
61
+ * If true we evaluate run-time performance by re-rendering test viewpoints.
62
+ * @type {boolean}
63
+ */
64
+ let gBenchmark = false;
65
+
66
+ /**
67
+ * For benchmarking with vsync on: render this many redundant images per frame.
68
+ * @type {number}
69
+ */
70
+ let gFrameMult = 1;
71
+
72
+ /**
73
+ * A web worker for parsing binary assets in a separate thread.
74
+ * @type {*}
75
+ */
76
+ let gLoadAssetsWorker = new WorkerPool(4, "../workers/loadpng.worker.js");
77
+
78
+
79
+ /**
80
+ * A web worker for merging slices together.
81
+ * @type {*}
82
+ */
83
+ let gCopySliceWorker = new WorkerPool(4, "../workers/copyslices.worker.js");
84
+
85
+ /**
86
+ * The vertex shader for rendering a baked MERF scene with ray marching.
87
+ * @const {string}
88
+ */
89
+ const kRayMarchVertexShader = `
90
+ varying vec3 vOrigin;
91
+ varying vec3 vDirection;
92
+ uniform mat4 world_T_cam;
93
+ uniform mat4 cam_T_clip;
94
+
95
+ void main() {
96
+ vec4 posClip = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
97
+ gl_Position = posClip;
98
+ posClip /= posClip.w;
99
+
100
+ vec4 originCam = vec4(0.0, 0.0, 0.0, 1.0);
101
+ vec4 nearPointCam = cam_T_clip * vec4(posClip.x, posClip.y, -1.0, 1.0);
102
+ nearPointCam /= -nearPointCam.z;
103
+
104
+ vec4 originWorld = world_T_cam * originCam;
105
+ vec4 nearPointWorld = world_T_cam * nearPointCam;
106
+ vOrigin = originWorld.xyz / originWorld.w;
107
+ vDirection = nearPointWorld.xyz / nearPointWorld.w - vOrigin;
108
+ }
109
+ `;
110
+
111
+ /**
112
+ * We build the ray marching shader programmatically, this string contains the
113
+ * header for the shader.
114
+ * @const {string}
115
+ */
116
+ const kRayMarchFragmentShaderHeader = `
117
+ precision highp float;
118
+
119
+ varying vec3 vOrigin;
120
+ varying vec3 vDirection;
121
+
122
+ uniform int displayMode;
123
+
124
+ uniform mat3 worldspaceROpengl;
125
+ uniform float nearPlane;
126
+
127
+ #ifdef USE_DISTANCE_GRID
128
+ uniform highp sampler3D distanceGrid;
129
+ uniform highp sampler3D occupancyGrid_L0;
130
+ #else
131
+ uniform highp sampler3D occupancyGrid_L0;
132
+ uniform highp sampler3D occupancyGrid_L1;
133
+ uniform highp sampler3D occupancyGrid_L2;
134
+ #ifndef USE_BITS
135
+ uniform highp sampler3D occupancyGrid_L3;
136
+ uniform highp sampler3D occupancyGrid_L4;
137
+ #endif
138
+ #endif
139
+
140
+ uniform vec4 bias_0[NUM_CHANNELS_ONE/4];
141
+ uniform vec4 bias_1[NUM_CHANNELS_TWO/4];
142
+ uniform vec4 bias_2[NUM_CHANNELS_THREE/4];
143
+
144
+ uniform highp sampler2D weightsZero;
145
+ uniform highp sampler2D weightsOne;
146
+ uniform highp sampler2D weightsTwo;
147
+
148
+ #ifdef USE_EXPOSURE
149
+ uniform float exposure;
150
+ #endif
151
+
152
+ uniform vec3 atlasSize;
153
+
154
+ uniform highp sampler3D sparseGridBlockIndices;
155
+ uniform highp sampler3D sparseGridDensity;
156
+ uniform highp sampler3D sparseGridRgb;
157
+ uniform highp sampler3D sparseGridFeatures;
158
+
159
+ // need to use texture arrays, otherwise we exceed max texture unit limit
160
+ uniform highp sampler2DArray planeDensity;
161
+ uniform highp sampler2DArray planeRgb;
162
+ uniform highp sampler2DArray planeFeatures;
163
+ `;
164
+
165
+
166
+ /**
167
+ * The THREE.js renderer object we use.
168
+ * @type {?THREE.WebGLRenderer}
169
+ */
170
+ let gRenderer = null;
171
+
172
+
173
+ /**
174
+ * The number of submodels
175
+ */
176
+ let gSubmodelCount = 1;
177
+
178
+
179
+ /**
180
+ * The perspective camera we use to view the scene.
181
+ * @type {?THREE.PerspectiveCamera}
182
+ */
183
+ let gCamera = null;
184
+
185
+
186
+ let gViewportDims = [640, 480];
.history/globals_20241204114937.js ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2024 The Google Research Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ /**
16
+ * @fileoverview Global state of the web viewer.
17
+ */
18
+
19
+ /**
20
+ * Our framerate display.
21
+ * @type {?Object}
22
+ */
23
+ let gStats = null;
24
+
25
+ /**
26
+ * If enabled, expect multiple submodels.
27
+ */
28
+ let gUseSubmodel = false;
29
+
30
+ /**
31
+ * Transform from world coordinates to the current submodel.
32
+ */
33
+ let gSubmodelTransform = null;
34
+
35
+ /**
36
+ * Deferred MLP parameters for the current submodel.
37
+ */
38
+ let gDeferredMlp = null;
39
+
40
+ /**
41
+ * Different display modes for debugging rendering.
42
+ * @enum {number}
43
+ */
44
+ const DisplayModeType = {
45
+ /** Runs the full model with view dependence. */
46
+ DISPLAY_NORMAL: 0,
47
+ /** Disables the view-dependence network. */
48
+ DISPLAY_DIFFUSE: 1,
49
+ /** Only shows the latent features. */
50
+ DISPLAY_FEATURES: 2,
51
+ /** Only shows the view dependent component. */
52
+ DISPLAY_VIEW_DEPENDENT: 3,
53
+ /** Only shows the coarse block grid. */
54
+ DISPLAY_COARSE_GRID: 4,
55
+ };
56
+
57
+ /** @type {!DisplayModeType} */
58
+ let gDisplayMode = DisplayModeType.DISPLAY_NORMAL;
59
+
60
+ /**
61
+ * If true we evaluate run-time performance by re-rendering test viewpoints.
62
+ * @type {boolean}
63
+ */
64
+ let gBenchmark = false;
65
+
66
+ /**
67
+ * For benchmarking with vsync on: render this many redundant images per frame.
68
+ * @type {number}
69
+ */
70
+ let gFrameMult = 1;
71
+
72
+ /**
73
+ * A web worker for parsing binary assets in a separate thread.
74
+ * @type {*}
75
+ */
76
+ let gLoadAssetsWorker = new WorkerPool(4, "loadpng.worker.js");
77
+
78
+
79
+ /**
80
+ * A web worker for merging slices together.
81
+ * @type {*}
82
+ */
83
+ let gCopySliceWorker = new WorkerPool(4, "../workers/copyslices.worker.js");
84
+
85
+ /**
86
+ * The vertex shader for rendering a baked MERF scene with ray marching.
87
+ * @const {string}
88
+ */
89
+ const kRayMarchVertexShader = `
90
+ varying vec3 vOrigin;
91
+ varying vec3 vDirection;
92
+ uniform mat4 world_T_cam;
93
+ uniform mat4 cam_T_clip;
94
+
95
+ void main() {
96
+ vec4 posClip = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
97
+ gl_Position = posClip;
98
+ posClip /= posClip.w;
99
+
100
+ vec4 originCam = vec4(0.0, 0.0, 0.0, 1.0);
101
+ vec4 nearPointCam = cam_T_clip * vec4(posClip.x, posClip.y, -1.0, 1.0);
102
+ nearPointCam /= -nearPointCam.z;
103
+
104
+ vec4 originWorld = world_T_cam * originCam;
105
+ vec4 nearPointWorld = world_T_cam * nearPointCam;
106
+ vOrigin = originWorld.xyz / originWorld.w;
107
+ vDirection = nearPointWorld.xyz / nearPointWorld.w - vOrigin;
108
+ }
109
+ `;
110
+
111
+ /**
112
+ * We build the ray marching shader programmatically, this string contains the
113
+ * header for the shader.
114
+ * @const {string}
115
+ */
116
+ const kRayMarchFragmentShaderHeader = `
117
+ precision highp float;
118
+
119
+ varying vec3 vOrigin;
120
+ varying vec3 vDirection;
121
+
122
+ uniform int displayMode;
123
+
124
+ uniform mat3 worldspaceROpengl;
125
+ uniform float nearPlane;
126
+
127
+ #ifdef USE_DISTANCE_GRID
128
+ uniform highp sampler3D distanceGrid;
129
+ uniform highp sampler3D occupancyGrid_L0;
130
+ #else
131
+ uniform highp sampler3D occupancyGrid_L0;
132
+ uniform highp sampler3D occupancyGrid_L1;
133
+ uniform highp sampler3D occupancyGrid_L2;
134
+ #ifndef USE_BITS
135
+ uniform highp sampler3D occupancyGrid_L3;
136
+ uniform highp sampler3D occupancyGrid_L4;
137
+ #endif
138
+ #endif
139
+
140
+ uniform vec4 bias_0[NUM_CHANNELS_ONE/4];
141
+ uniform vec4 bias_1[NUM_CHANNELS_TWO/4];
142
+ uniform vec4 bias_2[NUM_CHANNELS_THREE/4];
143
+
144
+ uniform highp sampler2D weightsZero;
145
+ uniform highp sampler2D weightsOne;
146
+ uniform highp sampler2D weightsTwo;
147
+
148
+ #ifdef USE_EXPOSURE
149
+ uniform float exposure;
150
+ #endif
151
+
152
+ uniform vec3 atlasSize;
153
+
154
+ uniform highp sampler3D sparseGridBlockIndices;
155
+ uniform highp sampler3D sparseGridDensity;
156
+ uniform highp sampler3D sparseGridRgb;
157
+ uniform highp sampler3D sparseGridFeatures;
158
+
159
+ // need to use texture arrays, otherwise we exceed max texture unit limit
160
+ uniform highp sampler2DArray planeDensity;
161
+ uniform highp sampler2DArray planeRgb;
162
+ uniform highp sampler2DArray planeFeatures;
163
+ `;
164
+
165
+
166
+ /**
167
+ * The THREE.js renderer object we use.
168
+ * @type {?THREE.WebGLRenderer}
169
+ */
170
+ let gRenderer = null;
171
+
172
+
173
+ /**
174
+ * The number of submodels
175
+ */
176
+ let gSubmodelCount = 1;
177
+
178
+
179
+ /**
180
+ * The perspective camera we use to view the scene.
181
+ * @type {?THREE.PerspectiveCamera}
182
+ */
183
+ let gCamera = null;
184
+
185
+
186
+ let gViewportDims = [640, 480];
.history/globals_20241204114940.js ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2024 The Google Research Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ /**
16
+ * @fileoverview Global state of the web viewer.
17
+ */
18
+
19
+ /**
20
+ * Our framerate display.
21
+ * @type {?Object}
22
+ */
23
+ let gStats = null;
24
+
25
+ /**
26
+ * If enabled, expect multiple submodels.
27
+ */
28
+ let gUseSubmodel = false;
29
+
30
+ /**
31
+ * Transform from world coordinates to the current submodel.
32
+ */
33
+ let gSubmodelTransform = null;
34
+
35
+ /**
36
+ * Deferred MLP parameters for the current submodel.
37
+ */
38
+ let gDeferredMlp = null;
39
+
40
+ /**
41
+ * Different display modes for debugging rendering.
42
+ * @enum {number}
43
+ */
44
+ const DisplayModeType = {
45
+ /** Runs the full model with view dependence. */
46
+ DISPLAY_NORMAL: 0,
47
+ /** Disables the view-dependence network. */
48
+ DISPLAY_DIFFUSE: 1,
49
+ /** Only shows the latent features. */
50
+ DISPLAY_FEATURES: 2,
51
+ /** Only shows the view dependent component. */
52
+ DISPLAY_VIEW_DEPENDENT: 3,
53
+ /** Only shows the coarse block grid. */
54
+ DISPLAY_COARSE_GRID: 4,
55
+ };
56
+
57
+ /** @type {!DisplayModeType} */
58
+ let gDisplayMode = DisplayModeType.DISPLAY_NORMAL;
59
+
60
+ /**
61
+ * If true we evaluate run-time performance by re-rendering test viewpoints.
62
+ * @type {boolean}
63
+ */
64
+ let gBenchmark = false;
65
+
66
+ /**
67
+ * For benchmarking with vsync on: render this many redundant images per frame.
68
+ * @type {number}
69
+ */
70
+ let gFrameMult = 1;
71
+
72
+ /**
73
+ * A web worker for parsing binary assets in a separate thread.
74
+ * @type {*}
75
+ */
76
+ let gLoadAssetsWorker = new WorkerPool(4, "loadpng.worker.js");
77
+
78
+
79
+ /**
80
+ * A web worker for merging slices together.
81
+ * @type {*}
82
+ */
83
+ let gCopySliceWorker = new WorkerPool(4, "copyslices.worker.js");
84
+
85
+ /**
86
+ * The vertex shader for rendering a baked MERF scene with ray marching.
87
+ * @const {string}
88
+ */
89
+ const kRayMarchVertexShader = `
90
+ varying vec3 vOrigin;
91
+ varying vec3 vDirection;
92
+ uniform mat4 world_T_cam;
93
+ uniform mat4 cam_T_clip;
94
+
95
+ void main() {
96
+ vec4 posClip = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
97
+ gl_Position = posClip;
98
+ posClip /= posClip.w;
99
+
100
+ vec4 originCam = vec4(0.0, 0.0, 0.0, 1.0);
101
+ vec4 nearPointCam = cam_T_clip * vec4(posClip.x, posClip.y, -1.0, 1.0);
102
+ nearPointCam /= -nearPointCam.z;
103
+
104
+ vec4 originWorld = world_T_cam * originCam;
105
+ vec4 nearPointWorld = world_T_cam * nearPointCam;
106
+ vOrigin = originWorld.xyz / originWorld.w;
107
+ vDirection = nearPointWorld.xyz / nearPointWorld.w - vOrigin;
108
+ }
109
+ `;
110
+
111
+ /**
112
+ * We build the ray marching shader programmatically, this string contains the
113
+ * header for the shader.
114
+ * @const {string}
115
+ */
116
+ const kRayMarchFragmentShaderHeader = `
117
+ precision highp float;
118
+
119
+ varying vec3 vOrigin;
120
+ varying vec3 vDirection;
121
+
122
+ uniform int displayMode;
123
+
124
+ uniform mat3 worldspaceROpengl;
125
+ uniform float nearPlane;
126
+
127
+ #ifdef USE_DISTANCE_GRID
128
+ uniform highp sampler3D distanceGrid;
129
+ uniform highp sampler3D occupancyGrid_L0;
130
+ #else
131
+ uniform highp sampler3D occupancyGrid_L0;
132
+ uniform highp sampler3D occupancyGrid_L1;
133
+ uniform highp sampler3D occupancyGrid_L2;
134
+ #ifndef USE_BITS
135
+ uniform highp sampler3D occupancyGrid_L3;
136
+ uniform highp sampler3D occupancyGrid_L4;
137
+ #endif
138
+ #endif
139
+
140
+ uniform vec4 bias_0[NUM_CHANNELS_ONE/4];
141
+ uniform vec4 bias_1[NUM_CHANNELS_TWO/4];
142
+ uniform vec4 bias_2[NUM_CHANNELS_THREE/4];
143
+
144
+ uniform highp sampler2D weightsZero;
145
+ uniform highp sampler2D weightsOne;
146
+ uniform highp sampler2D weightsTwo;
147
+
148
+ #ifdef USE_EXPOSURE
149
+ uniform float exposure;
150
+ #endif
151
+
152
+ uniform vec3 atlasSize;
153
+
154
+ uniform highp sampler3D sparseGridBlockIndices;
155
+ uniform highp sampler3D sparseGridDensity;
156
+ uniform highp sampler3D sparseGridRgb;
157
+ uniform highp sampler3D sparseGridFeatures;
158
+
159
+ // need to use texture arrays, otherwise we exceed max texture unit limit
160
+ uniform highp sampler2DArray planeDensity;
161
+ uniform highp sampler2DArray planeRgb;
162
+ uniform highp sampler2DArray planeFeatures;
163
+ `;
164
+
165
+
166
+ /**
167
+ * The THREE.js renderer object we use.
168
+ * @type {?THREE.WebGLRenderer}
169
+ */
170
+ let gRenderer = null;
171
+
172
+
173
+ /**
174
+ * The number of submodels
175
+ */
176
+ let gSubmodelCount = 1;
177
+
178
+
179
+ /**
180
+ * The perspective camera we use to view the scene.
181
+ * @type {?THREE.PerspectiveCamera}
182
+ */
183
+ let gCamera = null;
184
+
185
+
186
+ let gViewportDims = [640, 480];
.history/index_20241118162737.js ADDED
@@ -0,0 +1,549 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright 2024 The Google Research Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ /**
16
+ * @fileoverview Main driver for web viewer.
17
+ */
18
+ /**
19
+ * panel for current submodel
20
+ */
21
+ let gSubmodelPanel = null;
22
+ let gVMemPanel = null;
23
+
24
+ /**
25
+ * Number of sample points per voxel.
26
+ * @type {number}
27
+ */
28
+ let gStepMult = 1;
29
+
30
+
31
+ /**
32
+ * For large scenes with varying exposure we set this value to be the exposure
33
+ * of the virtual camera (shutter_speed_in_seconds * iso / 1000).
34
+ * @type {number}
35
+ */
36
+ let gExposure = null;
37
+
38
+
39
+ /**
40
+ * Loads full scene representation.
41
+ *
42
+ * This includes all submodel assets, including allocation and download.
43
+ *
44
+ * This function should be called exactly once.
45
+ *
46
+ * @param {string} dirUrl Either points to a directory that contains scene files
47
+ * or to a json file that maps virtual filenames to
48
+ * download links
49
+ * @param {!object} overrideParams A dictionary that contains overrides for the
50
+ * params in scene_params.json (e.g. combineMode, deferredMode or useBits).
51
+ */
52
+ function loadScene(dirUrl, overrideParams) {
53
+ // Check if dirUrl points to a json file or to a directory.
54
+ let filenameToLinkPromise;
55
+ if (dirUrl && dirUrl.includes('.json')) {
56
+ // If this is the case, we fetch a JSON file that maps filenames to links.
57
+ filenameToLinkPromise = loadJSONFile(dirUrl);
58
+ } else {
59
+ // Otherwise, the scene files directly lie at dirUrl and we create a
60
+ // dummy promise that resolves immediately.
61
+ filenameToLinkPromise = Promise.resolve(null);
62
+ console.error('dirUrl est null ou non valide. Le fichier Json est dans le dossier');
63
+ }
64
+
65
+ // This variable is defined in progressive.js.
66
+ filenameToLinkPromise
67
+ .then(filenameToLink => {
68
+ // Mapping from fake filenames to real filenames under root directory
69
+ // dirUrl.
70
+ const router = new Router(dirUrl, filenameToLink);
71
+ console.log('router:', router)
72
+
73
+ // Loads scene parameters (voxel grid size, view-dependence MLP).
74
+ const sceneParamsUrl = router.translate('scene_params.json');
75
+ console.log('sceneParamsUrl:',sceneParamsUrl);
76
+ const sceneParamsPromise = loadJSONFile(sceneParamsUrl);
77
+ console.log('sceneParamsPromise:',sceneParamsPromise);
78
+
79
+ if (overrideParams['loadBenchmarkCameras']) {
80
+ loadBenchmarkCameras(router);
81
+ }
82
+
83
+ // Some of the shader code is stored in seperate files.
84
+ return Promise.all([sceneParamsPromise, {router, filenameToLink}]);
85
+ })
86
+ .then(parsed => {
87
+ // scene_params.json for this scene.
88
+ // Translates filenames to full URLs.
89
+ const [sceneParams, carry] = parsed;
90
+
91
+ // Determine if there are multiple submodels or not. If so, figure out
92
+ // how many.
93
+ let initialSubmodelIndex = 0;
94
+ gUseSubmodel =
95
+ (sceneParams.hasOwnProperty('num_local_submodels') &&
96
+ sceneParams['num_local_submodels'] > 1);
97
+ if (gUseSubmodel) {
98
+ // Override default submodel to the user chose by URL.
99
+ gSubmodelCount = sceneParams['num_local_submodels'];
100
+ initialSubmodelIndex =
101
+ sceneParams['sm_to_params'][sceneParams['submodel_idx']];
102
+ }
103
+
104
+ // Get links to scene_params.json files for each submodel.
105
+ let sceneParamsPromises = [];
106
+ for (let si = 0; si < gSubmodelCount; ++si) {
107
+ // Get the submodel ids participating in this scene.
108
+ const submodelId = sceneParams['params_to_sm'][si];
109
+ // Find path to its scene_params.json file.
110
+ const filePath = carry.router.translate(
111
+ submodelAssetPath(submodelId, 'scene_params.json'));
112
+ // Construct path to scene_params.json for this submodel.
113
+ sceneParamsPromises.push(loadJSONFile(filePath));
114
+ }
115
+
116
+ // Wait for all scene_params.json files to be loaded.
117
+ return Promise.all(
118
+ [{...carry, initialSubmodelIndex}, ...sceneParamsPromises]);
119
+ })
120
+ .then(loaded => {
121
+ let [carry, ...submodelSceneParams] = loaded;
122
+ for (let si = 0; si < submodelSceneParams.length; ++si) {
123
+ // Override the scene params using the URL GET variables.
124
+ submodelSceneParams[si] =
125
+ extend(submodelSceneParams[si], overrideParams);
126
+
127
+ // Build fake-filename-to-real-filename translator for this
128
+ // submodel.
129
+ const submodelId = submodelSceneParams[si]['params_to_sm'][si];
130
+ let subDirUrl = dirUrl;
131
+ if (gUseSubmodel) {
132
+ subDirUrl = `${subDirUrl}/${submodelAssetPath(submodelId)}`;
133
+ }
134
+ let submodelRouter = new Router(subDirUrl, carry.filenameToLink);
135
+
136
+ // Load all assets related to this submodel. This is not a blocking
137
+ // operation.
138
+ // TODO: Consider loading this content on-demand and using an LRU
139
+ // cache to bound memory usage.
140
+ let submodelContent =
141
+ initializeSceneContent(submodelSceneParams[si], submodelRouter);
142
+ console.log(`spec for submodel #${si}:`, submodelContent.spec);
143
+
144
+ // Register submodel content with the texture manager.
145
+ registerSubmodelContent(si, submodelContent);
146
+ }
147
+
148
+ // Now that we know the submodel scale we can set the camera pose.
149
+ let si = carry.initialSubmodelIndex;
150
+ setupInitialCameraPose(
151
+ dirUrl,
152
+ submodelCenter(si, getSubmodelContent(si).params),
153
+ );
154
+
155
+ // Instantiate scene & texture buffers.
156
+ return Promise.all([si, initializeDeferredMlp(si)]);
157
+ }).then(([si, _]) => {
158
+ return initializePingPongBuffers(si);
159
+ }).then(() => {
160
+ return requestAnimationFrame(renderNextFrame);
161
+ });
162
+ }
163
+
164
+
165
+ // Initialiser la variable pour activer/désactiver les mouvements de la caméra
166
+ let disableCameraControls = false;
167
+ /**
168
+ * Initializes the application based on the URL parameters.
169
+ */
170
+ function initFromParameters() {
171
+ // HTTP GET query parameters
172
+ const params = new URL(window.location.href).searchParams;
173
+ console.log(params);
174
+
175
+ // Base directory for all assets.
176
+ const dirUrl = 'nyc/sm_004';
177
+ console.log(dirUrl);
178
+
179
+ // Controls platform-specific defaults: phone, low, medium, high. Not
180
+ // const as benchmark=true can override it.
181
+ let quality = params.get('quality');
182
+
183
+ // Initialize lowResFactor with a default value
184
+ let lowResFactor = parseInt(params.get('downscale') || 1, 10);
185
+
186
+ // Number of samples per voxel. Increase for slower rendering and fewer
187
+ // artifacts.
188
+
189
+ const stepMult = params.get('stepMult');
190
+ if (stepMult) {
191
+ gStepMult = parseInt(stepMult, 10);
192
+ }
193
+ const frameMult = params.get('frameMult');
194
+ if (frameMult) {
195
+ gFrameMult = parseInt(frameMult, 10);
196
+ }
197
+
198
+ // Manually specify exposure for exposure-aware models.
199
+ const exposure = params.get('exposure');
200
+ if (exposure) {
201
+ gExposure = parseFloat(exposure);
202
+ }
203
+
204
+ // For manually overriding parameters in scene_params.json.
205
+ let overrideParams = {};
206
+
207
+ const benchmarkParam = params.get('benchmark');
208
+ const benchmark = benchmarkParam &&
209
+ (benchmarkParam.toLowerCase() === 'time' ||
210
+ benchmarkParam.toLowerCase() === 'quality');
211
+ if (benchmark) {
212
+ overrideParams['loadBenchmarkCameras'] = true;
213
+ quality = 'high';
214
+ const sceneNameChunks = dirUrl.split('/').slice(-2);
215
+ setupBenchmarkStats(
216
+ sceneNameChunks[0] + '_' + sceneNameChunks[1],
217
+ benchmarkParam.toLowerCase() === 'quality');
218
+ }
219
+
220
+ // snerg, vfr
221
+ const deferredMode = params.get('deferredMode');
222
+ if (deferredMode) {
223
+ overrideParams['deferred_rendering_mode'] = deferredMode;
224
+ }
225
+
226
+ // sum, concat_and_sum
227
+ const combineMode = params.get('combineMode');
228
+ if (combineMode && combineMode === 'concat_and_sum') {
229
+ overrideParams['merge_features_combine_op'] = 'coarse_sum';
230
+ }
231
+
232
+ // are occupancy grids bitpacked?
233
+ const useBits = params.get('useBits');
234
+ if (useBits) {
235
+ overrideParams['useBits'] = useBits.toLowerCase() === 'true';
236
+ }
237
+
238
+ // Use distance grid for calculating step sizes.
239
+ const useDistanceGrid = params.get('useDistanceGrid');
240
+ if (useDistanceGrid) {
241
+ overrideParams['useDistanceGrid'] =
242
+ useDistanceGrid.toLowerCase() === 'true';
243
+ }
244
+
245
+ // Load legacy scenes, where the distance & occupancy grids are stored
246
+ // as a single monolithic file.
247
+ const legacyGrids = params.get('legacyGrids');
248
+ if (legacyGrids) {
249
+ overrideParams['legacyGrids'] = legacyGrids.toLowerCase() === 'true';
250
+ }
251
+
252
+ // Sets the activation function of the DeferredMLP. Either "relu" or "elu".
253
+ // Defaults to elu.
254
+ const activation = params.get('activation');
255
+ if (activation) {
256
+ overrideParams['activation'] = activation;
257
+ }
258
+
259
+ // Whether to use feature gating for the triplanes. Either "true" or "false".
260
+ // Defaults to true.
261
+ const featureGating = params.get('featureGating');
262
+ if (featureGating) {
263
+ overrideParams['feature_gating'] = featureGating.toLowerCase() === 'true';
264
+ }
265
+
266
+ // Limit the number of cached submodel payloads.
267
+ const submodelCacheSize = params.get('submodelCacheSize');
268
+ if (submodelCacheSize) {
269
+ gSubmodelCacheSize = Number(submodelCacheSize);
270
+ }
271
+
272
+ // Merge slices of assets together before binding to WebGL texture.
273
+ const mergeSlices = params.get('mergeSlices');
274
+ if (mergeSlices) {
275
+ overrideParams['merge_slices'] = mergeSlices == 'true';
276
+ }
277
+
278
+ // The background color (in hex, e.g. #FF0000 for red) that the scene is
279
+ // rendered on top of. Defaults to medium grey.
280
+ const backgroundColor = params.get('backgroundColor');
281
+ if (backgroundColor) {
282
+ overrideParams['backgroundColor'] = '#' + backgroundColor;
283
+ }
284
+
285
+
286
+
287
+ // Créer le conteneur de la vue et ajouter la classe
288
+ const view = document.createElement('div');
289
+ view.classList.add('view'); // Appliquer les styles de style.css
290
+
291
+ // Ajouter le conteneur de vue dans l'élément #viewspacecontainer avant de récupérer les dimensions
292
+ const viewSpaceContainer = document.getElementById('viewspacecontainer');
293
+ viewSpaceContainer.appendChild(view);
294
+
295
+ // Maintenant que l'élément est dans le DOM, on peut récupérer les dimensions définies par le CSS
296
+ function getCssDimensions(element) {
297
+ const styles = getComputedStyle(element);
298
+ const width = parseInt(styles.width, 10);
299
+ const height = parseInt(styles.height, 10);
300
+ return { width, height };
301
+ }
302
+
303
+ const { width: frameBufferWidth, height: frameBufferHeight } = getCssDimensions(view);
304
+
305
+ // Appliquer les dimensions récupérées si besoin (optionnel)
306
+ view.style.width = `${frameBufferWidth}px`;
307
+ view.style.height = `${frameBufferHeight}px`;
308
+
309
+ // Log dimensions for debugging
310
+ console.log('Width:', frameBufferWidth, 'Height:', frameBufferHeight);
311
+
312
+ // Continue with the rest of the script...
313
+
314
+
315
+ // Vous pouvez définir ici d'autres valeurs par défaut spécifiques
316
+
317
+ // Mouse mode: Default to "fps" if not set in the URL
318
+ const mouseMode = params.get('mouseMode') || 'orbit';
319
+
320
+ // No downscale factor specified, estimate it from the quality setting.
321
+ let stepSizeVisibilityDelay = 0.99;
322
+ if (!params.get('downscale') && quality) {
323
+ let maxPixelsPerFrame = frameBufferWidth * frameBufferHeight;
324
+ if (quality == 'phone') { // For iPhones.
325
+ maxPixelsPerFrame = 300 * 450;
326
+ stepSizeVisibilityDelay = 0.8;
327
+ } else if (quality == 'low') { // For laptops with integrated GPUs.
328
+ maxPixelsPerFrame = 600 * 250;
329
+ stepSizeVisibilityDelay = 0.8;
330
+ } else if (quality == 'medium') { // For laptops with dicrete GPUs.
331
+ maxPixelsPerFrame = 1200 * 640;
332
+ stepSizeVisibilityDelay = 0.95;
333
+ } // else assume quality is 'high' and render at full res.
334
+
335
+ while (frameBufferWidth * frameBufferHeight / lowResFactor >
336
+ maxPixelsPerFrame) {
337
+ lowResFactor++;
338
+ }
339
+
340
+ console.log('Automatically chose a downscaling factor of ' + lowResFactor);
341
+ }
342
+ overrideParams['useLargerStepsWhenOccluded'] = false;
343
+ overrideParams['step_size_visibility_delay'] = stepSizeVisibilityDelay;
344
+
345
+ // Near plane distance in world coordinates.
346
+ const nearPlane = parseFloat(params.get('near') || 0.01);
347
+
348
+ // FOV along screen height. Specified in degrees.
349
+ const vfovy = parseFloat(params.get('vfovy') || 40.0);
350
+
351
+
352
+ const viewSpace = document.querySelector('.viewspace');
353
+ viewSpace.textContent = '';
354
+ viewSpace.appendChild(view);
355
+
356
+ // Créer le canvas et l'attacher à .view
357
+ let canvas = document.createElement('canvas');
358
+ view.appendChild(canvas);
359
+
360
+ // Appliquer les styles du parent (.view) au canvas via JavaScript
361
+ canvas.style.width = '100%';
362
+ canvas.style.height = '100%';
363
+ canvas.style.border = getComputedStyle(view).border;
364
+ canvas.style.borderRadius = getComputedStyle(view).borderRadius;
365
+ canvas.style.boxSizing = getComputedStyle(view).boxSizing;
366
+
367
+ // Add tool for visualizing framerate.
368
+ gStats = Stats();
369
+ gStats.dom.style.position = 'absolute';
370
+ gStats.dom.style.display = 'none'; // Masquer complètement les stats
371
+ viewSpace.appendChild(gStats.dom);
372
+
373
+ gSubmodelPanel = gStats.addPanel(new Stats.Panel('SM', '#0ff', '#002'));
374
+ gSubmodelPanel.update(getActiveSubmodelIndex());
375
+
376
+ gVMemPanel = gStats.addPanel(new Stats.Panel('MB VRAM', '#0ff', '#002'));
377
+ gVMemPanel.update(0);
378
+
379
+ // Show FPS; hide other panels.
380
+ gStats.showPanel(0);
381
+
382
+ // Set up a high performance WebGL context, making sure that anti-aliasing is
383
+ // turned off.
384
+ let gl = canvas.getContext('webgl2', {
385
+ powerPreference: 'high-performance',
386
+ alpha: false,
387
+ stencil: true,
388
+ precision: 'highp',
389
+ depth: true,
390
+ antialias: false,
391
+ desynchronized: false,
392
+ preserveDrawingBuffer:
393
+ benchmarkParam && benchmarkParam.toLowerCase() === 'quality',
394
+ });
395
+ gl.enable(gl.DEPTH_TEST); // Activer le test de profondeur
396
+ gl.depthFunc(gl.LEQUAL); // Spécifier comment les comparaisons de profondeur doivent être effectuées
397
+ gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
398
+ gl.viewport(0, 0, canvas.width, canvas.height);
399
+
400
+ gRenderer = new THREE.WebGLRenderer({
401
+ canvas: canvas,
402
+ context: gl,
403
+ });
404
+
405
+ // Set up the normal scene used for rendering.
406
+ gCamera = new THREE.PerspectiveCamera(
407
+ vfovy, // Vertical field of view (kept from your original setup)
408
+ Math.trunc(view.offsetWidth / lowResFactor) /
409
+ Math.trunc(view.offsetHeight / lowResFactor), // Aspect ratio (adjusted based on view size)
410
+ nearPlane, // Near clipping plane (keep your original value)
411
+ 2000 // Far clipping plane, increased from 100.0 to 2000. Adjust as needed for your scene
412
+ );
413
+ gCamera.updateProjectionMatrix();
414
+
415
+ // Expose gCamera to global scope
416
+ window.sceneCamera = gCamera;
417
+
418
+ // Set up progressive rendering and renderer size (keeping your existing code)
419
+ setupProgressiveRendering(view, lowResFactor);
420
+ gRenderer.autoClear = false;
421
+ gRenderer.setSize(view.offsetWidth, view.offsetHeight);
422
+ // Enable depth testing
423
+ gRenderer.setClearColor(0x000000, 1);
424
+
425
+ setupCameraControls(mouseMode, view); // Using the default 'fps' if not specified
426
+
427
+ let width = Math.trunc(view.offsetWidth / lowResFactor);
428
+ let height = Math.trunc(view.offsetHeight / lowResFactor);
429
+ setupViewport(width, height);
430
+
431
+ loadScene(dirUrl, overrideParams)
432
+ }
433
+
434
+
435
+ let sphereAdded = false;
436
+ /**
437
+ * The main update function that gets called every frame.
438
+ *
439
+ * @param {number} t elapsed time between frames (ms).
440
+ */
441
+ function renderNextFrame(t) {
442
+ // Delete old submodels to keep memory usage in check.
443
+ garbageCollectSubmodelPayloads();
444
+
445
+ // Attempt to set the current ray march scene. This will kick off the process
446
+ // of instantiating a new scene if necessary.
447
+ let submodelIndex =
448
+ positionToSubmodel(gCamera.position, getActiveSubmodelContent().params);
449
+ setCurrentRayMarchScene(submodelIndex);
450
+
451
+ // setCurrentRayMarchScene() may not actually change the scene. Use the
452
+ // index of the current active submodel instead.
453
+ submodelIndex = getActiveSubmodelIndex();
454
+
455
+ let sceneParams = getSubmodelContent(submodelIndex).params;
456
+
457
+ for (let i = 0; i < gFrameMult; ++i) {
458
+ gSubmodelTransform = submodelTransform(submodelIndex, sceneParams);
459
+
460
+ gSubmodelPanel.update(submodelIndex);
461
+ gVMemPanel.update(getCurrentTextureUsageInBytes() / 1e6);
462
+ // Condition pour désactiver les mouvements de la caméra lors du hover
463
+ if (!disableCameraControls) {
464
+ updateCameraControls(); // Mettre à jour les contrôles de la caméra uniquement si hover désactivé
465
+ }
466
+
467
+ // For benchmarking, we want to direcly set the projection matrix.
468
+ if (!gBenchmark) {
469
+ gCamera.updateProjectionMatrix();
470
+ }
471
+ gCamera.updateMatrixWorld();
472
+
473
+ const currentSubmodelCenter = submodelCenter(submodelIndex, sceneParams);
474
+ const submodelScale = getSubmodelScale(submodelIndex);
475
+ let submodelCameraPosition = new THREE.Vector3().copy(gCamera.position);
476
+ submodelCameraPosition.sub(currentSubmodelCenter);
477
+ submodelCameraPosition.multiplyScalar(submodelScale);
478
+
479
+ let shaderUniforms = getRayMarchScene().children[0].material.uniforms;
480
+ // Make sure to free up GPU memory from the previous frames.
481
+ if (!!shaderUniforms['weightsZero']['value']) {
482
+ shaderUniforms['weightsZero']['value'].dispose();
483
+ }
484
+ if (!!shaderUniforms['weightsOne']['value']) {
485
+ shaderUniforms['weightsOne']['value'].dispose();
486
+ }
487
+ if (!!shaderUniforms['weightsTwo']['value']) {
488
+ shaderUniforms['weightsTwo']['value'].dispose();
489
+ }
490
+
491
+ shaderUniforms['bias_0']['value'] =
492
+ trilerpDeferredMlpBiases(submodelIndex, 0, submodelCameraPosition);
493
+ shaderUniforms['bias_1']['value'] =
494
+ trilerpDeferredMlpBiases(submodelIndex, 1, submodelCameraPosition);
495
+ shaderUniforms['bias_2']['value'] =
496
+ trilerpDeferredMlpBiases(submodelIndex, 2, submodelCameraPosition);
497
+
498
+ shaderUniforms['weightsZero']['value'] =
499
+ trilerpDeferredMlpKernel(submodelIndex, 0, submodelCameraPosition);
500
+ shaderUniforms['weightsOne']['value'] =
501
+ trilerpDeferredMlpKernel(submodelIndex, 1, submodelCameraPosition);
502
+ shaderUniforms['weightsTwo']['value'] =
503
+ trilerpDeferredMlpKernel(submodelIndex, 2, submodelCameraPosition);
504
+
505
+
506
+ gRenderer.clear();
507
+ renderProgressively(); // Clear depth buffer to avoid depth conflicts
508
+ gRenderer.render(gSphereScene, gCamera);
509
+ }
510
+ gStats.update();
511
+
512
+ // By default we schedule the next frame ASAP, but the benchmark mode can
513
+ // override this by replacing this lambda.
514
+ let scheduleNextFrame = () => {
515
+ requestAnimationFrame(renderNextFrame);
516
+ };
517
+ if (gBenchmark) {
518
+ scheduleNextFrame = benchmarkPerformance(scheduleNextFrame);
519
+ }
520
+ scheduleNextFrame();
521
+ }
522
+
523
+
524
+
525
+ /**
526
+ * Starts the volumetric scene viewer application.
527
+ */
528
+ function start() {
529
+ initFromParameters();
530
+ addHandlers();
531
+
532
+ // Initialiser la caméra et le renderer avant d'utiliser gCamera et gRenderer
533
+ if (!gCamera || !gRenderer) {
534
+ console.error("gCamera ou gRenderer non initialisés.");
535
+ return;
536
+ }
537
+ // Après avoir initialisé gCamera et gRenderer
538
+ addInteractionPlane();
539
+ setupNewPlaneGizmo(newPlane);
540
+ setupMouseHover();
541
+ // Ajouter les écouteurs d'événements pour les mouvements de la souris et les clics
542
+ window.addEventListener('mousemove', onMouseMove, false);
543
+ window.addEventListener('mousedown', onMouseDown, false);
544
+ window.addEventListener('mouseup', onMouseUp, false);
545
+
546
+
547
+ }
548
+
549
+ window.onload = start;
.history/index_20241119000624.html ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Personnalisation</title>
7
+ <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
9
+ <link href="/dist/tailwind.css" rel="stylesheet">
10
+ </head>
11
+ <body class="bg-bg text-textDark font-sans">
12
+ <div id="dashboard-layout" class="flex flex-col h-screen">
13
+ <div id="content" class="flex flex-col flex-1 p-6">
14
+ <!-- Error Message -->
15
+ <div id="error" class="hidden text-red-600"></div>
16
+
17
+ <!-- Viewspace Container -->
18
+ <div id="viewspacecontainer" class="bg-white p-6 rounded-lg shadow-md">
19
+ <div class="view aspect-w-16 aspect-h-9 rounded-xl border border-yellow-300 bg-gray-100 flex items-center justify-center">
20
+ <!-- Loading Animation -->
21
+ <div id="Loading" class="absolute">
22
+ <h4 class="text-lg font-bold text-gray-700">
23
+ <span id="image-progress">Loading images: 0/?</span>
24
+ </h4>
25
+ </div>
26
+ <!-- Benchmark Stats -->
27
+ <textarea readonly id="benchmark-stats" rows="10" cols="40"
28
+ class="absolute top-4 left-4 border rounded p-2 text-gray-600 bg-white shadow">
29
+ Click me to start benchmarking when the frame-rate is behaving reasonably.
30
+ </textarea>
31
+ <!-- Loading Indicators -->
32
+ <div id="loading-container" class="absolute flex space-x-4">
33
+ <div id="topleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
34
+ <div id="bottomleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
35
+ <div id="topright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
36
+ <div id="bottomright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
37
+ <div id="loading-indicator" class="w-8 h-8 bg-gray-500 rounded-full animate-spin"></div>
38
+ </div>
39
+ <!-- Viewer Canvas -->
40
+ <canvas id="viewerCanvas" class="w-full h-full rounded-xl"></canvas>
41
+ </div>
42
+ </div>
43
+
44
+ <!-- Toolbar -->
45
+ <div id="toolbar" class="flex flex-wrap items-center mt-6 space-x-4">
46
+ <button id="addSphereButton" class="bg-blue-600 text-white px-4 py-2 rounded">Ajouter une pièce</button>
47
+ <button id="toggleGizmoButton" class="bg-gray-300 text-black px-4 py-2 rounded">Guizmo inactif</button>
48
+ <button id="togglePlanButton" class="bg-green-600 text-white px-4 py-2 rounded">Plan visible</button>
49
+ <button id="toggleNewPlaneGizmoButton" class="bg-gray-300 text-black px-4 py-2 rounded">Gizmo Plan2 Inactif</button>
50
+ <button id="createNewPlaneButton" class="bg-blue-600 text-white px-4 py-2 rounded">Créer un Nouveau Plan</button>
51
+ <button id="verifyButton" class="bg-yellow-500 text-white px-4 py-2 rounded">Vérifier</button>
52
+ <button id="boundingBoxButton" class="bg-purple-500 text-white px-4 py-2 rounded">Créer la bounding box</button>
53
+ <input type="text" id="folderPathInput" placeholder="Nom du dossier"
54
+ class="border rounded px-4 py-2 focus:outline-none">
55
+ <button id="uploadButton" class="bg-gray-400 text-white px-4 py-2 rounded" disabled>Téléverser vers GCS</button>
56
+ </div>
57
+
58
+ <!-- Video Maker Bar -->
59
+ <div id="videoMakerBar" class="flex flex-wrap items-center mt-6 space-x-4">
60
+ <button id="saveCameraPosition" class="bg-green-600 text-white px-4 py-2 rounded">Enregistrer Position Caméra</button>
61
+ <button id="stopAnimationButton" class="bg-red-600 text-white px-4 py-2 rounded">Arrêter l'Animation</button>
62
+ <button id="startAnimationButton" class="bg-blue-600 text-white px-4 py-2 rounded">Démarrer Animation Caméra</button>
63
+ <button id="captureButton" class="bg-purple-500 text-white px-4 py-2 rounded">Capturer Vidéo</button>
64
+ </div>
65
+
66
+ <!-- Status Message -->
67
+ <div id="statusMessage" class="status-message mt-4 text-gray-700"></div>
68
+
69
+ <!-- Figure Cards Container -->
70
+ <div id="figureCardsContainer" class="grid grid-cols-3 gap-4 mt-6">
71
+ <!-- Dynamic content will be added here -->
72
+ </div>
73
+ </div>
74
+ </div>
75
+
76
+ <!-- Charger dynamiquement les scripts avec logs -->
77
+ <script src="/js/layout.js"></script>
78
+ <script src="/js/sidebar.js"></script>
79
+ <script src="/js/topbar.js"></script>
80
+
81
+ <script>
82
+ const scriptsToLoad = [
83
+ 'https://unpkg.com/three@0.113.1/build/three.js',
84
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/OrbitControls.js',
85
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/PointerLockControls.js',
86
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/TransformControls.js',
87
+ 'https://unpkg.com/stats-js@1.0.1/build/stats.min.js',
88
+ 'https://cdn.jsdelivr.net/npm/ccapture.js@1.0.9/build/CCapture.all.min.js',
89
+ 'https://unpkg.com/file-saver@2.0.0-rc.2/dist/FileSaver.min.js',
90
+ '/dashboard/personnalisation/deps/zlib.js',
91
+ '/dashboard/personnalisation/deps/png.js',
92
+ '/dashboard/personnalisation/scene_spec.js',
93
+ '/dashboard/personnalisation/fetch_asset.js',
94
+ '/dashboard/personnalisation/create_texture.js',
95
+ '/dashboard/personnalisation/prepare_payload.js',
96
+ '/dashboard/personnalisation/populate_texture.js',
97
+ '/dashboard/personnalisation/texture_manager.js',
98
+ '/dashboard/personnalisation/worker_pool.js',
99
+ '/dashboard/personnalisation/globals.js',
100
+ '/dashboard/personnalisation/utils.js',
101
+ '/dashboard/personnalisation/progressive.js',
102
+ '/dashboard/personnalisation/viewdependency.js',
103
+ '/dashboard/personnalisation/defaultposes.js',
104
+ '/dashboard/personnalisation/input.js',
105
+ '/dashboard/personnalisation/benchmark.js',
106
+ '/dashboard/personnalisation/custom/objects.js',
107
+ '/dashboard/personnalisation/custom/boutons_sb.js',
108
+ '/dashboard/personnalisation/custom/mouseHover.js',
109
+ '/dashboard/personnalisation/custom/addSphereOnClick.js',
110
+ '/dashboard/personnalisation/custom/selectFigure.js',
111
+ '/dashboard/personnalisation/custom/extrude.js',
112
+ '/dashboard/personnalisation/local_script.js',
113
+ '/dashboard/personnalisation/videoMaker/cameraCapture.js',
114
+ '/dashboard/personnalisation/index.js'
115
+ ];
116
+
117
+ async function loadScriptsInOrder(scripts) {
118
+ for (const script of scripts) {
119
+ await new Promise((resolve, reject) => {
120
+ const scriptEl = document.createElement('script');
121
+ scriptEl.src = script;
122
+ scriptEl.onload = resolve;
123
+ scriptEl.onerror = reject;
124
+ document.body.appendChild(scriptEl);
125
+ });
126
+ }
127
+ }
128
+
129
+ loadScriptsInOrder(scriptsToLoad);
130
+ </script>
131
+ </body>
132
+ </html>
.history/index_20241119234025.html ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Personnalisation</title>
7
+ </head>
8
+ <body class="bg-bg text-textDark font-sans">
9
+ <div id="dashboard-layout" class="flex flex-col h-screen">
10
+ <div id="content" class="flex flex-col flex-1 p-6">
11
+ <!-- Error Message -->
12
+ <div id="error" class="hidden text-red-600"></div>
13
+
14
+ <!-- Viewspace Container -->
15
+ <div id="viewspacecontainer" class="bg-white p-6 rounded-lg shadow-md">
16
+ <div class="view aspect-w-16 aspect-h-9 rounded-xl border border-yellow-300 bg-gray-100 flex items-center justify-center">
17
+ <!-- Loading Animation -->
18
+ <div id="Loading" class="absolute">
19
+ <h4 class="text-lg font-bold text-gray-700">
20
+ <span id="image-progress">Loading images: 0/?</span>
21
+ </h4>
22
+ </div>
23
+ <!-- Benchmark Stats -->
24
+ <textarea readonly id="benchmark-stats" rows="10" cols="40"
25
+ class="absolute top-4 left-4 border rounded p-2 text-gray-600 bg-white shadow">
26
+ Click me to start benchmarking when the frame-rate is behaving reasonably.
27
+ </textarea>
28
+ <!-- Loading Indicators -->
29
+ <div id="loading-container" class="absolute flex space-x-4">
30
+ <div id="topleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
31
+ <div id="bottomleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
32
+ <div id="topright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
33
+ <div id="bottomright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
34
+ <div id="loading-indicator" class="w-8 h-8 bg-gray-500 rounded-full animate-spin"></div>
35
+ </div>
36
+ <!-- Viewer Canvas -->
37
+ <canvas id="viewerCanvas" class="w-full h-full rounded-xl"></canvas>
38
+ </div>
39
+ </div>
40
+
41
+ <!-- Toolbar -->
42
+ <div id="toolbar" class="flex flex-wrap items-center mt-6 space-x-4">
43
+ <button id="addSphereButton" class="bg-blue-600 text-white px-4 py-2 rounded">Ajouter une pièce</button>
44
+ <button id="toggleGizmoButton" class="bg-gray-300 text-black px-4 py-2 rounded">Guizmo inactif</button>
45
+ <button id="togglePlanButton" class="bg-green-600 text-white px-4 py-2 rounded">Plan visible</button>
46
+ <button id="toggleNewPlaneGizmoButton" class="bg-gray-300 text-black px-4 py-2 rounded">Gizmo Plan2 Inactif</button>
47
+ <button id="createNewPlaneButton" class="bg-blue-600 text-white px-4 py-2 rounded">Créer un Nouveau Plan</button>
48
+ <button id="verifyButton" class="bg-yellow-500 text-white px-4 py-2 rounded">Vérifier</button>
49
+ <button id="boundingBoxButton" class="bg-purple-500 text-white px-4 py-2 rounded">Créer la bounding box</button>
50
+ <input type="text" id="folderPathInput" placeholder="Nom du dossier"
51
+ class="border rounded px-4 py-2 focus:outline-none">
52
+ <button id="uploadButton" class="bg-gray-400 text-white px-4 py-2 rounded" disabled>Téléverser vers GCS</button>
53
+ </div>
54
+
55
+ <!-- Video Maker Bar -->
56
+ <div id="videoMakerBar" class="flex flex-wrap items-center mt-6 space-x-4">
57
+ <button id="saveCameraPosition" class="bg-green-600 text-white px-4 py-2 rounded">Enregistrer Position Caméra</button>
58
+ <button id="stopAnimationButton" class="bg-red-600 text-white px-4 py-2 rounded">Arrêter l'Animation</button>
59
+ <button id="startAnimationButton" class="bg-blue-600 text-white px-4 py-2 rounded">Démarrer Animation Caméra</button>
60
+ <button id="captureButton" class="bg-purple-500 text-white px-4 py-2 rounded">Capturer Vidéo</button>
61
+ </div>
62
+
63
+ <!-- Status Message -->
64
+ <div id="statusMessage" class="status-message mt-4 text-gray-700"></div>
65
+
66
+ <!-- Figure Cards Container -->
67
+ <div id="figureCardsContainer" class="grid grid-cols-3 gap-4 mt-6">
68
+ <!-- Dynamic content will be added here -->
69
+ </div>
70
+ </div>
71
+ </div>
72
+
73
+ <!-- Charger dynamiquement les scripts avec logs -->
74
+ <script src="/js/layout.js"></script>
75
+ <script src="/js/sidebar.js"></script>
76
+ <script src="/js/topbar.js"></script>
77
+
78
+ <script>
79
+ const scriptsToLoad = [
80
+ 'https://unpkg.com/three@0.113.1/build/three.js',
81
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/OrbitControls.js',
82
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/PointerLockControls.js',
83
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/TransformControls.js',
84
+ 'https://unpkg.com/stats-js@1.0.1/build/stats.min.js',
85
+ 'https://cdn.jsdelivr.net/npm/ccapture.js@1.0.9/build/CCapture.all.min.js',
86
+ 'https://unpkg.com/file-saver@2.0.0-rc.2/dist/FileSaver.min.js',
87
+ '/dashboard/personnalisation/deps/zlib.js',
88
+ '/dashboard/personnalisation/deps/png.js',
89
+ '/dashboard/personnalisation/scene_spec.js',
90
+ '/dashboard/personnalisation/fetch_asset.js',
91
+ '/dashboard/personnalisation/create_texture.js',
92
+ '/dashboard/personnalisation/prepare_payload.js',
93
+ '/dashboard/personnalisation/populate_texture.js',
94
+ '/dashboard/personnalisation/texture_manager.js',
95
+ '/dashboard/personnalisation/worker_pool.js',
96
+ '/dashboard/personnalisation/globals.js',
97
+ '/dashboard/personnalisation/utils.js',
98
+ '/dashboard/personnalisation/progressive.js',
99
+ '/dashboard/personnalisation/viewdependency.js',
100
+ '/dashboard/personnalisation/defaultposes.js',
101
+ '/dashboard/personnalisation/input.js',
102
+ '/dashboard/personnalisation/benchmark.js',
103
+ '/dashboard/personnalisation/custom/objects.js',
104
+ '/dashboard/personnalisation/custom/boutons_sb.js',
105
+ '/dashboard/personnalisation/custom/mouseHover.js',
106
+ '/dashboard/personnalisation/custom/addSphereOnClick.js',
107
+ '/dashboard/personnalisation/custom/selectFigure.js',
108
+ '/dashboard/personnalisation/custom/extrude.js',
109
+ '/dashboard/personnalisation/local_script.js',
110
+ '/dashboard/personnalisation/videoMaker/cameraCapture.js',
111
+ '/dashboard/personnalisation/index.js'
112
+ ];
113
+
114
+ async function loadScriptsInOrder(scripts) {
115
+ for (const script of scripts) {
116
+ await new Promise((resolve, reject) => {
117
+ const scriptEl = document.createElement('script');
118
+ scriptEl.src = script;
119
+ scriptEl.onload = resolve;
120
+ scriptEl.onerror = reject;
121
+ document.body.appendChild(scriptEl);
122
+ });
123
+ }
124
+ }
125
+
126
+ loadScriptsInOrder(scriptsToLoad);
127
+ </script>
128
+ </body>
129
+ </html>
.history/index_20241119234048.html ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Personnalisation</title>
7
+ </head>
8
+ <body class="bg-bg text-textDark font-sans">
9
+ <div id="dashboard-layout" class="flex flex-col h-screen">
10
+ <div id="content" class="flex flex-col flex-1 p-6">
11
+ <!-- Error Message -->
12
+ <div id="error" class="hidden text-red-600"></div>
13
+
14
+ <!-- Viewspace Container -->
15
+ <div id="viewspacecontainer" class="bg-white p-6 rounded-lg shadow-md">
16
+ <div class="view aspect-w-16 aspect-h-9 rounded-xl border border-yellow-300 bg-gray-100 flex items-center justify-center">
17
+ <!-- Loading Animation -->
18
+ <div id="Loading" class="absolute">
19
+ <h4 class="text-lg font-bold text-gray-700">
20
+ <span id="image-progress">Loading images: 0/?</span>
21
+ </h4>
22
+ </div>
23
+ <!-- Benchmark Stats -->
24
+ <textarea readonly id="benchmark-stats" rows="10" cols="40"
25
+ class="absolute top-4 left-4 border rounded p-2 text-gray-600 bg-white shadow">
26
+ Click me to start benchmarking when the frame-rate is behaving reasonably.
27
+ </textarea>
28
+ <!-- Loading Indicators -->
29
+ <div id="loading-container" class="absolute flex space-x-4">
30
+ <div id="topleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
31
+ <div id="bottomleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
32
+ <div id="topright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
33
+ <div id="bottomright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
34
+ <div id="loading-indicator" class="w-8 h-8 bg-gray-500 rounded-full animate-spin"></div>
35
+ </div>
36
+ <!-- Viewer Canvas -->
37
+ <canvas id="viewerCanvas" class="w-full h-full rounded-xl"></canvas>
38
+ </div>
39
+ </div>
40
+
41
+ </div>
42
+ </div>
43
+
44
+ <!-- Charger dynamiquement les scripts avec logs -->
45
+ <script src="/js/layout.js"></script>
46
+ <script src="/js/sidebar.js"></script>
47
+ <script src="/js/topbar.js"></script>
48
+
49
+ <script>
50
+ const scriptsToLoad = [
51
+ 'https://unpkg.com/three@0.113.1/build/three.js',
52
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/OrbitControls.js',
53
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/PointerLockControls.js',
54
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/TransformControls.js',
55
+ 'https://unpkg.com/stats-js@1.0.1/build/stats.min.js',
56
+ 'https://cdn.jsdelivr.net/npm/ccapture.js@1.0.9/build/CCapture.all.min.js',
57
+ 'https://unpkg.com/file-saver@2.0.0-rc.2/dist/FileSaver.min.js',
58
+ '/dashboard/personnalisation/deps/zlib.js',
59
+ '/dashboard/personnalisation/deps/png.js',
60
+ '/dashboard/personnalisation/scene_spec.js',
61
+ '/dashboard/personnalisation/fetch_asset.js',
62
+ '/dashboard/personnalisation/create_texture.js',
63
+ '/dashboard/personnalisation/prepare_payload.js',
64
+ '/dashboard/personnalisation/populate_texture.js',
65
+ '/dashboard/personnalisation/texture_manager.js',
66
+ '/dashboard/personnalisation/worker_pool.js',
67
+ '/dashboard/personnalisation/globals.js',
68
+ '/dashboard/personnalisation/utils.js',
69
+ '/dashboard/personnalisation/progressive.js',
70
+ '/dashboard/personnalisation/viewdependency.js',
71
+ '/dashboard/personnalisation/defaultposes.js',
72
+ '/dashboard/personnalisation/input.js',
73
+ '/dashboard/personnalisation/benchmark.js',
74
+ '/dashboard/personnalisation/custom/objects.js',
75
+ '/dashboard/personnalisation/custom/boutons_sb.js',
76
+ '/dashboard/personnalisation/custom/mouseHover.js',
77
+ '/dashboard/personnalisation/custom/addSphereOnClick.js',
78
+ '/dashboard/personnalisation/custom/selectFigure.js',
79
+ '/dashboard/personnalisation/custom/extrude.js',
80
+ '/dashboard/personnalisation/local_script.js',
81
+ '/dashboard/personnalisation/videoMaker/cameraCapture.js',
82
+ '/dashboard/personnalisation/index.js'
83
+ ];
84
+
85
+ async function loadScriptsInOrder(scripts) {
86
+ for (const script of scripts) {
87
+ await new Promise((resolve, reject) => {
88
+ const scriptEl = document.createElement('script');
89
+ scriptEl.src = script;
90
+ scriptEl.onload = resolve;
91
+ scriptEl.onerror = reject;
92
+ document.body.appendChild(scriptEl);
93
+ });
94
+ }
95
+ }
96
+
97
+ loadScriptsInOrder(scriptsToLoad);
98
+ </script>
99
+ </body>
100
+ </html>
.history/index_20241119234054.html ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Personnalisation</title>
7
+ </head>
8
+ <body class="bg-bg text-textDark font-sans">
9
+ <div id="dashboard-layout" class="flex flex-col h-screen">
10
+ <div id="content" class="flex flex-col flex-1 p-6">
11
+ <!-- Error Message -->
12
+ <div id="error" class="hidden text-red-600"></div>
13
+
14
+ <!-- Viewspace Container -->
15
+ <div id="viewspacecontainer" class="bg-white p-6 rounded-lg shadow-md">
16
+ <div class="view aspect-w-16 aspect-h-9 rounded-xl border border-yellow-300 bg-gray-100 flex items-center justify-center">
17
+ <!-- Loading Animation -->
18
+ <div id="Loading" class="absolute">
19
+ <h4 class="text-lg font-bold text-gray-700">
20
+ <span id="image-progress">Loading images: 0/?</span>
21
+ </h4>
22
+ </div>
23
+ <!-- Benchmark Stats -->
24
+ <textarea readonly id="benchmark-stats" rows="10" cols="40"
25
+ class="absolute top-4 left-4 border rounded p-2 text-gray-600 bg-white shadow">
26
+ Click me to start benchmarking when the frame-rate is behaving reasonably.
27
+ </textarea>
28
+ <!-- Loading Indicators -->
29
+ <div id="loading-container" class="absolute flex space-x-4">
30
+ <div id="topleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
31
+ <div id="bottomleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
32
+ <div id="topright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
33
+ <div id="bottomright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
34
+ <div id="loading-indicator" class="w-8 h-8 bg-gray-500 rounded-full animate-spin"></div>
35
+ </div>
36
+ <!-- Viewer Canvas -->
37
+ <canvas id="viewerCanvas" class="w-full h-full rounded-xl"></canvas>
38
+ </div>
39
+ </div>
40
+
41
+ </div>
42
+ </div>
43
+
44
+ <script>
45
+ const scriptsToLoad = [
46
+ 'https://unpkg.com/three@0.113.1/build/three.js',
47
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/OrbitControls.js',
48
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/PointerLockControls.js',
49
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/TransformControls.js',
50
+ 'https://unpkg.com/stats-js@1.0.1/build/stats.min.js',
51
+ 'https://cdn.jsdelivr.net/npm/ccapture.js@1.0.9/build/CCapture.all.min.js',
52
+ 'https://unpkg.com/file-saver@2.0.0-rc.2/dist/FileSaver.min.js',
53
+ '/dashboard/personnalisation/deps/zlib.js',
54
+ '/dashboard/personnalisation/deps/png.js',
55
+ '/dashboard/personnalisation/scene_spec.js',
56
+ '/dashboard/personnalisation/fetch_asset.js',
57
+ '/dashboard/personnalisation/create_texture.js',
58
+ '/dashboard/personnalisation/prepare_payload.js',
59
+ '/dashboard/personnalisation/populate_texture.js',
60
+ '/dashboard/personnalisation/texture_manager.js',
61
+ '/dashboard/personnalisation/worker_pool.js',
62
+ '/dashboard/personnalisation/globals.js',
63
+ '/dashboard/personnalisation/utils.js',
64
+ '/dashboard/personnalisation/progressive.js',
65
+ '/dashboard/personnalisation/viewdependency.js',
66
+ '/dashboard/personnalisation/defaultposes.js',
67
+ '/dashboard/personnalisation/input.js',
68
+ '/dashboard/personnalisation/benchmark.js',
69
+ '/dashboard/personnalisation/custom/objects.js',
70
+ '/dashboard/personnalisation/custom/boutons_sb.js',
71
+ '/dashboard/personnalisation/custom/mouseHover.js',
72
+ '/dashboard/personnalisation/custom/addSphereOnClick.js',
73
+ '/dashboard/personnalisation/custom/selectFigure.js',
74
+ '/dashboard/personnalisation/custom/extrude.js',
75
+ '/dashboard/personnalisation/local_script.js',
76
+ '/dashboard/personnalisation/videoMaker/cameraCapture.js',
77
+ '/dashboard/personnalisation/index.js'
78
+ ];
79
+
80
+ async function loadScriptsInOrder(scripts) {
81
+ for (const script of scripts) {
82
+ await new Promise((resolve, reject) => {
83
+ const scriptEl = document.createElement('script');
84
+ scriptEl.src = script;
85
+ scriptEl.onload = resolve;
86
+ scriptEl.onerror = reject;
87
+ document.body.appendChild(scriptEl);
88
+ });
89
+ }
90
+ }
91
+
92
+ loadScriptsInOrder(scriptsToLoad);
93
+ </script>
94
+ </body>
95
+ </html>
.history/index_20241119234122.html ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Personnalisation</title>
7
+ </head>
8
+ <body class="bg-bg text-textDark font-sans">
9
+ <div id="dashboard-layout" class="flex flex-col h-screen">
10
+ <div id="content" class="flex flex-col flex-1 p-6">
11
+ <!-- Error Message -->
12
+ <div id="error" class="hidden text-red-600"></div>
13
+
14
+ <!-- Viewspace Container -->
15
+ <div id="viewspacecontainer" class="bg-white p-6 rounded-lg shadow-md">
16
+ <div class="view aspect-w-16 aspect-h-9 rounded-xl border border-yellow-300 bg-gray-100 flex items-center justify-center">
17
+ <!-- Loading Animation -->
18
+ <div id="Loading" class="absolute">
19
+ <h4 class="text-lg font-bold text-gray-700">
20
+ <span id="image-progress">Loading images: 0/?</span>
21
+ </h4>
22
+ </div>
23
+ <!-- Benchmark Stats -->
24
+ <textarea readonly id="benchmark-stats" rows="10" cols="40"
25
+ class="absolute top-4 left-4 border rounded p-2 text-gray-600 bg-white shadow">
26
+ Click me to start benchmarking when the frame-rate is behaving reasonably.
27
+ </textarea>
28
+ <!-- Loading Indicators -->
29
+ <div id="loading-container" class="absolute flex space-x-4">
30
+ <div id="topleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
31
+ <div id="bottomleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
32
+ <div id="topright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
33
+ <div id="bottomright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
34
+ <div id="loading-indicator" class="w-8 h-8 bg-gray-500 rounded-full animate-spin"></div>
35
+ </div>
36
+ <!-- Viewer Canvas -->
37
+ <canvas id="viewerCanvas" class="w-full h-full rounded-xl"></canvas>
38
+ </div>
39
+ </div>
40
+
41
+ </div>
42
+ </div>
43
+
44
+ <script>
45
+ const scriptsToLoad = [
46
+ 'https://unpkg.com/three@0.113.1/build/three.js',
47
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/OrbitControls.js',
48
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/PointerLockControls.js',
49
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/TransformControls.js',
50
+ 'https://unpkg.com/stats-js@1.0.1/build/stats.min.js',
51
+ 'https://cdn.jsdelivr.net/npm/ccapture.js@1.0.9/build/CCapture.all.min.js',
52
+ 'https://unpkg.com/file-saver@2.0.0-rc.2/dist/FileSaver.min.js',
53
+ 'deps/zlib.js',
54
+ 'deps/png.js',
55
+ 'scene_spec.js',
56
+ 'fetch_asset.js',
57
+ 'create_texture.js',
58
+ 'prepare_payload.js',
59
+ 'populate_texture.js',
60
+ 'texture_manager.js',
61
+ 'worker_pool.js',
62
+ 'globals.js',
63
+ 'utils.js',
64
+ 'progressive.js',
65
+ 'viewdependency.js',
66
+ 'defaultposes.js',
67
+ 'input.js',
68
+ 'benchmark.js',
69
+ 'custom/objects.js',
70
+ 'custom/boutons_sb.js',
71
+ 'custom/mouseHover.js',
72
+ 'custom/addSphereOnClick.js',
73
+ 'custom/selectFigure.js',
74
+ 'custom/extrude.js',
75
+ 'local_script.js',
76
+ 'videoMaker/cameraCapture.js',
77
+ 'index.js'
78
+ ];
79
+
80
+ async function loadScriptsInOrder(scripts) {
81
+ for (const script of scripts) {
82
+ await new Promise((resolve, reject) => {
83
+ const scriptEl = document.createElement('script');
84
+ scriptEl.src = script;
85
+ scriptEl.onload = resolve;
86
+ scriptEl.onerror = reject;
87
+ document.body.appendChild(scriptEl);
88
+ });
89
+ }
90
+ }
91
+
92
+ loadScriptsInOrder(scriptsToLoad);
93
+ </script>
94
+ </body>
95
+ </html>
.history/index_20241119234131.html ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Personnalisation</title>
7
+ </head>
8
+ <body class="bg-bg text-textDark font-sans">
9
+ <div id="dashboard-layout" class="flex flex-col h-screen">
10
+ <div id="content" class="flex flex-col flex-1 p-6">
11
+ <!-- Error Message -->
12
+ <div id="error" class="hidden text-red-600"></div>
13
+
14
+ <!-- Viewspace Container -->
15
+ <div id="viewspacecontainer" class="bg-white p-6 rounded-lg shadow-md">
16
+ <div class="view aspect-w-16 aspect-h-9 rounded-xl border border-yellow-300 bg-gray-100 flex items-center justify-center">
17
+ <!-- Loading Animation -->
18
+ <div id="Loading" class="absolute">
19
+ <h4 class="text-lg font-bold text-gray-700">
20
+ <span id="image-progress">Loading images: 0/?</span>
21
+ </h4>
22
+ </div>
23
+ <!-- Benchmark Stats -->
24
+ <textarea readonly id="benchmark-stats" rows="10" cols="40"
25
+ class="absolute top-4 left-4 border rounded p-2 text-gray-600 bg-white shadow">
26
+ Click me to start benchmarking when the frame-rate is behaving reasonably.
27
+ </textarea>
28
+ <!-- Loading Indicators -->
29
+ <div id="loading-container" class="absolute flex space-x-4">
30
+ <div id="topleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
31
+ <div id="bottomleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
32
+ <div id="topright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
33
+ <div id="bottomright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
34
+ <div id="loading-indicator" class="w-8 h-8 bg-gray-500 rounded-full animate-spin"></div>
35
+ </div>
36
+ <!-- Viewer Canvas -->
37
+ <canvas id="viewerCanvas" class="w-full h-full rounded-xl"></canvas>
38
+ </div>
39
+ </div>
40
+
41
+ </div>
42
+ </div>
43
+
44
+ <script>
45
+ const scriptsToLoad = [
46
+ 'https://unpkg.com/three@0.113.1/build/three.js',
47
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/OrbitControls.js',
48
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/PointerLockControls.js',
49
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/TransformControls.js',
50
+ 'https://unpkg.com/stats-js@1.0.1/build/stats.min.js',
51
+ 'https://cdn.jsdelivr.net/npm/ccapture.js@1.0.9/build/CCapture.all.min.js',
52
+ 'https://unpkg.com/file-saver@2.0.0-rc.2/dist/FileSaver.min.js',
53
+ 'deps/zlib.js',
54
+ 'deps/png.js',
55
+ 'scene_spec.js',
56
+ 'fetch_asset.js',
57
+ 'create_texture.js',
58
+ 'prepare_payload.js',
59
+ 'populate_texture.js',
60
+ 'texture_manager.js',
61
+ 'worker_pool.js',
62
+ 'globals.js',
63
+ 'utils.js',
64
+ 'progressive.js',
65
+ 'viewdependency.js',
66
+ 'defaultposes.js',
67
+ 'input.js',
68
+ 'benchmark.js',
69
+
70
+ 'local_script.js',
71
+ 'videoMaker/cameraCapture.js',
72
+ 'index.js'
73
+ ];
74
+
75
+ async function loadScriptsInOrder(scripts) {
76
+ for (const script of scripts) {
77
+ await new Promise((resolve, reject) => {
78
+ const scriptEl = document.createElement('script');
79
+ scriptEl.src = script;
80
+ scriptEl.onload = resolve;
81
+ scriptEl.onerror = reject;
82
+ document.body.appendChild(scriptEl);
83
+ });
84
+ }
85
+ }
86
+
87
+ loadScriptsInOrder(scriptsToLoad);
88
+ </script>
89
+ </body>
90
+ </html>
.history/index_20241119234135.html ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Personnalisation</title>
7
+ </head>
8
+ <body class="bg-bg text-textDark font-sans">
9
+ <div id="dashboard-layout" class="flex flex-col h-screen">
10
+ <div id="content" class="flex flex-col flex-1 p-6">
11
+ <!-- Error Message -->
12
+ <div id="error" class="hidden text-red-600"></div>
13
+
14
+ <!-- Viewspace Container -->
15
+ <div id="viewspacecontainer" class="bg-white p-6 rounded-lg shadow-md">
16
+ <div class="view aspect-w-16 aspect-h-9 rounded-xl border border-yellow-300 bg-gray-100 flex items-center justify-center">
17
+ <!-- Loading Animation -->
18
+ <div id="Loading" class="absolute">
19
+ <h4 class="text-lg font-bold text-gray-700">
20
+ <span id="image-progress">Loading images: 0/?</span>
21
+ </h4>
22
+ </div>
23
+ <!-- Benchmark Stats -->
24
+ <textarea readonly id="benchmark-stats" rows="10" cols="40"
25
+ class="absolute top-4 left-4 border rounded p-2 text-gray-600 bg-white shadow">
26
+ Click me to start benchmarking when the frame-rate is behaving reasonably.
27
+ </textarea>
28
+ <!-- Loading Indicators -->
29
+ <div id="loading-container" class="absolute flex space-x-4">
30
+ <div id="topleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
31
+ <div id="bottomleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
32
+ <div id="topright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
33
+ <div id="bottomright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
34
+ <div id="loading-indicator" class="w-8 h-8 bg-gray-500 rounded-full animate-spin"></div>
35
+ </div>
36
+ <!-- Viewer Canvas -->
37
+ <canvas id="viewerCanvas" class="w-full h-full rounded-xl"></canvas>
38
+ </div>
39
+ </div>
40
+
41
+ </div>
42
+ </div>
43
+
44
+ <script>
45
+ const scriptsToLoad = [
46
+ 'https://unpkg.com/three@0.113.1/build/three.js',
47
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/OrbitControls.js',
48
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/PointerLockControls.js',
49
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/TransformControls.js',
50
+ 'https://unpkg.com/stats-js@1.0.1/build/stats.min.js',
51
+ 'https://cdn.jsdelivr.net/npm/ccapture.js@1.0.9/build/CCapture.all.min.js',
52
+ 'https://unpkg.com/file-saver@2.0.0-rc.2/dist/FileSaver.min.js',
53
+ 'deps/zlib.js',
54
+ 'deps/png.js',
55
+ 'scene_spec.js',
56
+ 'fetch_asset.js',
57
+ 'create_texture.js',
58
+ 'prepare_payload.js',
59
+ 'populate_texture.js',
60
+ 'texture_manager.js',
61
+ 'worker_pool.js',
62
+ 'globals.js',
63
+ 'utils.js',
64
+ 'progressive.js',
65
+ 'viewdependency.js',
66
+ 'defaultposes.js',
67
+ 'input.js',
68
+ 'benchmark.js',
69
+
70
+ 'local_script.js',
71
+
72
+ 'index.js'
73
+ ];
74
+
75
+ async function loadScriptsInOrder(scripts) {
76
+ for (const script of scripts) {
77
+ await new Promise((resolve, reject) => {
78
+ const scriptEl = document.createElement('script');
79
+ scriptEl.src = script;
80
+ scriptEl.onload = resolve;
81
+ scriptEl.onerror = reject;
82
+ document.body.appendChild(scriptEl);
83
+ });
84
+ }
85
+ }
86
+
87
+ loadScriptsInOrder(scriptsToLoad);
88
+ </script>
89
+ </body>
90
+ </html>
.history/index_20241119235124.html ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Personnalisation</title>
7
+ </head>
8
+ <body class="bg-bg text-textDark font-sans">
9
+ <div id="dashboard-layout" class="flex flex-col h-screen">
10
+ <div id="content" class="flex flex-col flex-1 p-6">
11
+ <!-- Error Message -->
12
+ <div id="error" class="hidden text-red-600"></div>
13
+
14
+ <!-- Viewspace Container -->
15
+ <div id="viewspacecontainer" class="bg-white p-6 rounded-lg shadow-md">
16
+ <div class="view aspect-w-16 aspect-h-9 rounded-xl border border-yellow-300 bg-gray-100 flex items-center justify-center">
17
+ <!-- Loading Animation -->
18
+ <div id="Loading" class="absolute">
19
+ <h4 class="text-lg font-bold text-gray-700">
20
+ <span id="image-progress">Loading images: 0/?</span>
21
+ </h4>
22
+ </div>
23
+ <!-- Benchmark Stats -->
24
+ <textarea readonly id="benchmark-stats" rows="10" cols="40"
25
+ class="absolute top-4 left-4 border rounded p-2 text-gray-600 bg-white shadow">
26
+ Click me to start benchmarking when the frame-rate is behaving reasonably.
27
+ </textarea>
28
+ <!-- Loading Indicators -->
29
+ <div id="loading-container" class="absolute flex space-x-4">
30
+ <div id="topleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
31
+ <div id="bottomleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
32
+ <div id="topright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
33
+ <div id="bottomright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
34
+ <div id="loading-indicator" class="w-8 h-8 bg-gray-500 rounded-full animate-spin"></div>
35
+ </div>
36
+ <!-- Viewer Canvas -->
37
+ <canvas id="viewerCanvas" class="w-full h-full rounded-xl"></canvas>
38
+ </div>
39
+ </div>
40
+
41
+ </div>
42
+ </div>
43
+
44
+ <script src="combined.min.js"></script>
45
+
46
+ </body>
47
+ </html>
.history/index_20241119235326.html ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Personnalisation</title>
7
+ </head>
8
+ <body class="bg-bg text-textDark font-sans">
9
+ <div id="dashboard-layout" class="flex flex-col h-screen">
10
+ <div id="content" class="flex flex-col flex-1 p-6">
11
+ <!-- Error Message -->
12
+ <div id="error" class="hidden text-red-600"></div>
13
+
14
+ <!-- Viewspace Container -->
15
+ <div id="viewspacecontainer" class="bg-white p-6 rounded-lg shadow-md">
16
+ <div class="view aspect-w-16 aspect-h-9 rounded-xl border border-yellow-300 bg-gray-100 flex items-center justify-center">
17
+ <!-- Loading Animation -->
18
+ <div id="Loading" class="absolute">
19
+ <h4 class="text-lg font-bold text-gray-700">
20
+ <span id="image-progress">Loading images: 0/?</span>
21
+ </h4>
22
+ </div>
23
+ <!-- Benchmark Stats -->
24
+ <textarea readonly id="benchmark-stats" rows="10" cols="40"
25
+ class="absolute top-4 left-4 border rounded p-2 text-gray-600 bg-white shadow">
26
+ Click me to start benchmarking when the frame-rate is behaving reasonably.
27
+ </textarea>
28
+ <!-- Loading Indicators -->
29
+ <div id="loading-container" class="absolute flex space-x-4">
30
+ <div id="topleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
31
+ <div id="bottomleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
32
+ <div id="topright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
33
+ <div id="bottomright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
34
+ <div id="loading-indicator" class="w-8 h-8 bg-gray-500 rounded-full animate-spin"></div>
35
+ </div>
36
+ <!-- Viewer Canvas -->
37
+ <canvas id="viewerCanvas" class="w-full h-full rounded-xl"></canvas>
38
+ </div>
39
+ </div>
40
+
41
+ </div>
42
+ </div>
43
+
44
+ <script>
45
+ const scriptsToLoad = [
46
+ 'https://unpkg.com/three@0.113.1/build/three.js',
47
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/OrbitControls.js',
48
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/PointerLockControls.js',
49
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/TransformControls.js',
50
+ 'https://unpkg.com/stats-js@1.0.1/build/stats.min.js',
51
+ 'https://cdn.jsdelivr.net/npm/ccapture.js@1.0.9/build/CCapture.all.min.js',
52
+ 'https://unpkg.com/file-saver@2.0.0-rc.2/dist/FileSaver.min.js',
53
+ 'deps/zlib.js',
54
+ 'deps/png.js',
55
+ 'scene_spec.js',
56
+ 'fetch_asset.js',
57
+ 'create_texture.js',
58
+ 'prepare_payload.js',
59
+ 'populate_texture.js',
60
+ 'texture_manager.js',
61
+ 'worker_pool.js',
62
+ 'globals.js',
63
+ 'utils.js',
64
+ 'progressive.js',
65
+ 'viewdependency.js',
66
+ 'defaultposes.js',
67
+ 'input.js',
68
+ 'benchmark.js',
69
+
70
+ 'local_script.js',
71
+
72
+ 'index.js'
73
+ ];
74
+
75
+ async function loadScriptsInOrder(scripts) {
76
+ for (const script of scripts) {
77
+ await new Promise((resolve, reject) => {
78
+ const scriptEl = document.createElement('script');
79
+ scriptEl.src = script;
80
+ scriptEl.onload = resolve;
81
+ scriptEl.onerror = reject;
82
+ document.body.appendChild(scriptEl);
83
+ });
84
+ }
85
+ }
86
+
87
+ loadScriptsInOrder(scriptsToLoad);
88
+ </script>
89
+ </body>
90
+ </html>
.history/index_20241119235341.html ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Personnalisation</title>
7
+ </head>
8
+ <body class="bg-bg text-textDark font-sans">
9
+ <div id="dashboard-layout" class="flex flex-col h-screen">
10
+ <div id="content" class="flex flex-col flex-1 p-6">
11
+ <!-- Error Message -->
12
+ <div id="error" class="hidden text-red-600"></div>
13
+
14
+ <!-- Viewspace Container -->
15
+ <div id="viewspacecontainer" class="bg-white p-6 rounded-lg shadow-md">
16
+ <div class="view aspect-w-16 aspect-h-9 rounded-xl border border-yellow-300 bg-gray-100 flex items-center justify-center">
17
+ <!-- Loading Animation -->
18
+ <div id="Loading" class="absolute">
19
+ <h4 class="text-lg font-bold text-gray-700">
20
+ <span id="image-progress">Loading images: 0/?</span>
21
+ </h4>
22
+ </div>
23
+ <!-- Benchmark Stats -->
24
+ <textarea readonly id="benchmark-stats" rows="10" cols="40"
25
+ class="absolute top-4 left-4 border rounded p-2 text-gray-600 bg-white shadow">
26
+ Click me to start benchmarking when the frame-rate is behaving reasonably.
27
+ </textarea>
28
+ <!-- Loading Indicators -->
29
+ <div id="loading-container" class="absolute flex space-x-4">
30
+ <div id="topleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
31
+ <div id="bottomleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
32
+ <div id="topright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
33
+ <div id="bottomright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
34
+ <div id="loading-indicator" class="w-8 h-8 bg-gray-500 rounded-full animate-spin"></div>
35
+ </div>
36
+ <!-- Viewer Canvas -->
37
+ <canvas id="viewerCanvas" class="w-full h-full rounded-xl"></canvas>
38
+ </div>
39
+ </div>
40
+
41
+ </div>
42
+ </div>
43
+
44
+ <script>
45
+ const scriptsToLoad = [
46
+ 'https://unpkg.com/three@0.113.1/build/three.js',
47
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/OrbitControls.js',
48
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/PointerLockControls.js',
49
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/TransformControls.js',
50
+ 'https://unpkg.com/stats-js@1.0.1/build/stats.min.js',
51
+ 'https://cdn.jsdelivr.net/npm/ccapture.js@1.0.9/build/CCapture.all.min.js',
52
+ 'https://unpkg.com/file-saver@2.0.0-rc.2/dist/FileSaver.min.js',
53
+
54
+ ];
55
+
56
+ async function loadScriptsInOrder(scripts) {
57
+ for (const script of scripts) {
58
+ await new Promise((resolve, reject) => {
59
+ const scriptEl = document.createElement('script');
60
+ scriptEl.src = script;
61
+ scriptEl.onload = resolve;
62
+ scriptEl.onerror = reject;
63
+ document.body.appendChild(scriptEl);
64
+ });
65
+ }
66
+ }
67
+
68
+ loadScriptsInOrder(scriptsToLoad);
69
+ </script>
70
+ </body>
71
+ </html>
.history/index_20241119235343.html ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Personnalisation</title>
7
+ </head>
8
+ <body class="bg-bg text-textDark font-sans">
9
+ <div id="dashboard-layout" class="flex flex-col h-screen">
10
+ <div id="content" class="flex flex-col flex-1 p-6">
11
+ <!-- Error Message -->
12
+ <div id="error" class="hidden text-red-600"></div>
13
+
14
+ <!-- Viewspace Container -->
15
+ <div id="viewspacecontainer" class="bg-white p-6 rounded-lg shadow-md">
16
+ <div class="view aspect-w-16 aspect-h-9 rounded-xl border border-yellow-300 bg-gray-100 flex items-center justify-center">
17
+ <!-- Loading Animation -->
18
+ <div id="Loading" class="absolute">
19
+ <h4 class="text-lg font-bold text-gray-700">
20
+ <span id="image-progress">Loading images: 0/?</span>
21
+ </h4>
22
+ </div>
23
+ <!-- Benchmark Stats -->
24
+ <textarea readonly id="benchmark-stats" rows="10" cols="40"
25
+ class="absolute top-4 left-4 border rounded p-2 text-gray-600 bg-white shadow">
26
+ Click me to start benchmarking when the frame-rate is behaving reasonably.
27
+ </textarea>
28
+ <!-- Loading Indicators -->
29
+ <div id="loading-container" class="absolute flex space-x-4">
30
+ <div id="topleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
31
+ <div id="bottomleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
32
+ <div id="topright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
33
+ <div id="bottomright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
34
+ <div id="loading-indicator" class="w-8 h-8 bg-gray-500 rounded-full animate-spin"></div>
35
+ </div>
36
+ <!-- Viewer Canvas -->
37
+ <canvas id="viewerCanvas" class="w-full h-full rounded-xl"></canvas>
38
+ </div>
39
+ </div>
40
+
41
+ </div>
42
+ </div>
43
+
44
+ <script>
45
+ const scriptsToLoad = [
46
+ 'https://unpkg.com/three@0.113.1/build/three.js',
47
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/OrbitControls.js',
48
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/PointerLockControls.js',
49
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/TransformControls.js',
50
+ 'https://unpkg.com/stats-js@1.0.1/build/stats.min.js',
51
+ 'https://cdn.jsdelivr.net/npm/ccapture.js@1.0.9/build/CCapture.all.min.js',
52
+ 'https://unpkg.com/file-saver@2.0.0-rc.2/dist/FileSaver.min.js',
53
+ ''
54
+ ];
55
+
56
+ async function loadScriptsInOrder(scripts) {
57
+ for (const script of scripts) {
58
+ await new Promise((resolve, reject) => {
59
+ const scriptEl = document.createElement('script');
60
+ scriptEl.src = script;
61
+ scriptEl.onload = resolve;
62
+ scriptEl.onerror = reject;
63
+ document.body.appendChild(scriptEl);
64
+ });
65
+ }
66
+ }
67
+
68
+ loadScriptsInOrder(scriptsToLoad);
69
+ </script>
70
+ </body>
71
+ </html>
.history/index_20241119235345.html ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Personnalisation</title>
7
+ </head>
8
+ <body class="bg-bg text-textDark font-sans">
9
+ <div id="dashboard-layout" class="flex flex-col h-screen">
10
+ <div id="content" class="flex flex-col flex-1 p-6">
11
+ <!-- Error Message -->
12
+ <div id="error" class="hidden text-red-600"></div>
13
+
14
+ <!-- Viewspace Container -->
15
+ <div id="viewspacecontainer" class="bg-white p-6 rounded-lg shadow-md">
16
+ <div class="view aspect-w-16 aspect-h-9 rounded-xl border border-yellow-300 bg-gray-100 flex items-center justify-center">
17
+ <!-- Loading Animation -->
18
+ <div id="Loading" class="absolute">
19
+ <h4 class="text-lg font-bold text-gray-700">
20
+ <span id="image-progress">Loading images: 0/?</span>
21
+ </h4>
22
+ </div>
23
+ <!-- Benchmark Stats -->
24
+ <textarea readonly id="benchmark-stats" rows="10" cols="40"
25
+ class="absolute top-4 left-4 border rounded p-2 text-gray-600 bg-white shadow">
26
+ Click me to start benchmarking when the frame-rate is behaving reasonably.
27
+ </textarea>
28
+ <!-- Loading Indicators -->
29
+ <div id="loading-container" class="absolute flex space-x-4">
30
+ <div id="topleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
31
+ <div id="bottomleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
32
+ <div id="topright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
33
+ <div id="bottomright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
34
+ <div id="loading-indicator" class="w-8 h-8 bg-gray-500 rounded-full animate-spin"></div>
35
+ </div>
36
+ <!-- Viewer Canvas -->
37
+ <canvas id="viewerCanvas" class="w-full h-full rounded-xl"></canvas>
38
+ </div>
39
+ </div>
40
+
41
+ </div>
42
+ </div>
43
+
44
+ <script>
45
+ const scriptsToLoad = [
46
+ 'https://unpkg.com/three@0.113.1/build/three.js',
47
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/OrbitControls.js',
48
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/PointerLockControls.js',
49
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/TransformControls.js',
50
+ 'https://unpkg.com/stats-js@1.0.1/build/stats.min.js',
51
+ 'https://cdn.jsdelivr.net/npm/ccapture.js@1.0.9/build/CCapture.all.min.js',
52
+ 'https://unpkg.com/file-saver@2.0.0-rc.2/dist/FileSaver.min.js',
53
+ 'co'
54
+ ];
55
+
56
+ async function loadScriptsInOrder(scripts) {
57
+ for (const script of scripts) {
58
+ await new Promise((resolve, reject) => {
59
+ const scriptEl = document.createElement('script');
60
+ scriptEl.src = script;
61
+ scriptEl.onload = resolve;
62
+ scriptEl.onerror = reject;
63
+ document.body.appendChild(scriptEl);
64
+ });
65
+ }
66
+ }
67
+
68
+ loadScriptsInOrder(scriptsToLoad);
69
+ </script>
70
+ </body>
71
+ </html>
.history/index_20241119235353.html ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Personnalisation</title>
7
+ </head>
8
+ <body class="bg-bg text-textDark font-sans">
9
+ <div id="dashboard-layout" class="flex flex-col h-screen">
10
+ <div id="content" class="flex flex-col flex-1 p-6">
11
+ <!-- Error Message -->
12
+ <div id="error" class="hidden text-red-600"></div>
13
+
14
+ <!-- Viewspace Container -->
15
+ <div id="viewspacecontainer" class="bg-white p-6 rounded-lg shadow-md">
16
+ <div class="view aspect-w-16 aspect-h-9 rounded-xl border border-yellow-300 bg-gray-100 flex items-center justify-center">
17
+ <!-- Loading Animation -->
18
+ <div id="Loading" class="absolute">
19
+ <h4 class="text-lg font-bold text-gray-700">
20
+ <span id="image-progress">Loading images: 0/?</span>
21
+ </h4>
22
+ </div>
23
+ <!-- Benchmark Stats -->
24
+ <textarea readonly id="benchmark-stats" rows="10" cols="40"
25
+ class="absolute top-4 left-4 border rounded p-2 text-gray-600 bg-white shadow">
26
+ Click me to start benchmarking when the frame-rate is behaving reasonably.
27
+ </textarea>
28
+ <!-- Loading Indicators -->
29
+ <div id="loading-container" class="absolute flex space-x-4">
30
+ <div id="topleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
31
+ <div id="bottomleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
32
+ <div id="topright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
33
+ <div id="bottomright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
34
+ <div id="loading-indicator" class="w-8 h-8 bg-gray-500 rounded-full animate-spin"></div>
35
+ </div>
36
+ <!-- Viewer Canvas -->
37
+ <canvas id="viewerCanvas" class="w-full h-full rounded-xl"></canvas>
38
+ </div>
39
+ </div>
40
+
41
+ </div>
42
+ </div>
43
+
44
+ <script>
45
+ const scriptsToLoad = [
46
+ 'https://unpkg.com/three@0.113.1/build/three.js',
47
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/OrbitControls.js',
48
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/PointerLockControls.js',
49
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/TransformControls.js',
50
+ 'https://unpkg.com/stats-js@1.0.1/build/stats.min.js',
51
+ 'https://cdn.jsdelivr.net/npm/ccapture.js@1.0.9/build/CCapture.all.min.js',
52
+ 'https://unpkg.com/file-saver@2.0.0-rc.2/dist/FileSaver.min.js',
53
+ 'combined.min.js'
54
+ ];
55
+
56
+ async function loadScriptsInOrder(scripts) {
57
+ for (const script of scripts) {
58
+ await new Promise((resolve, reject) => {
59
+ const scriptEl = document.createElement('script');
60
+ scriptEl.src = script;
61
+ scriptEl.onload = resolve;
62
+ scriptEl.onerror = reject;
63
+ document.body.appendChild(scriptEl);
64
+ });
65
+ }
66
+ }
67
+
68
+ loadScriptsInOrder(scriptsToLoad);
69
+ </script>
70
+ </body>
71
+ </html>
.history/index_20241119235401.html ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Personnalisation</title>
7
+ </head>
8
+ <body class="bg-bg text-textDark font-sans">
9
+ <div id="dashboard-layout" class="flex flex-col h-screen">
10
+ <div id="content" class="flex flex-col flex-1 p-6">
11
+ <!-- Error Message -->
12
+ <div id="error" class="hidden text-red-600"></div>
13
+
14
+ <!-- Viewspace Container -->
15
+ <div id="viewspacecontainer" class="bg-white p-6 rounded-lg shadow-md">
16
+ <div class="view aspect-w-16 aspect-h-9 rounded-xl border border-yellow-300 bg-gray-100 flex items-center justify-center">
17
+ <!-- Loading Animation -->
18
+ <div id="Loading" class="absolute">
19
+ <h4 class="text-lg font-bold text-gray-700">
20
+ <span id="image-progress">Loading images: 0/?</span>
21
+ </h4>
22
+ </div>
23
+ <!-- Benchmark Stats -->
24
+ <textarea readonly id="benchmark-stats" rows="10" cols="40"
25
+ class="absolute top-4 left-4 border rounded p-2 text-gray-600 bg-white shadow">
26
+ Click me to start benchmarking when the frame-rate is behaving reasonably.
27
+ </textarea>
28
+ <!-- Loading Indicators -->
29
+ <div id="loading-container" class="absolute flex space-x-4">
30
+ <div id="topleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
31
+ <div id="bottomleft" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
32
+ <div id="topright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
33
+ <div id="bottomright" class="loading-bgbox w-8 h-8 bg-gray-300 rounded-full"></div>
34
+ <div id="loading-indicator" class="w-8 h-8 bg-gray-500 rounded-full animate-spin"></div>
35
+ </div>
36
+ <!-- Viewer Canvas -->
37
+ <canvas id="viewerCanvas" class="w-full h-full rounded-xl"></canvas>
38
+ </div>
39
+ </div>
40
+
41
+ </div>
42
+ </div>
43
+
44
+ <script>
45
+ const scriptsToLoad = [
46
+ 'https://unpkg.com/three@0.113.1/build/three.js',
47
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/OrbitControls.js',
48
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/PointerLockControls.js',
49
+ 'https://unpkg.com/three@0.113.1/examples/js/controls/TransformControls.js',
50
+ 'https://unpkg.com/stats-js@1.0.1/build/stats.min.js',
51
+ 'https://cdn.jsdelivr.net/npm/ccapture.js@1.0.9/build/CCapture.all.min.js',
52
+ 'https://unpkg.com/file-saver@2.0.0-rc.2/dist/FileSaver.min.js',
53
+ 'combined.min.js',
54
+ ];
55
+
56
+ async function loadScriptsInOrder(scripts) {
57
+ for (const script of scripts) {
58
+ await new Promise((resolve, reject) => {
59
+ const scriptEl = document.createElement('script');
60
+ scriptEl.src = script;
61
+ scriptEl.onload = resolve;
62
+ scriptEl.onerror = reject;
63
+ document.body.appendChild(scriptEl);
64
+ });
65
+ }
66
+ }
67
+
68
+ loadScriptsInOrder(scriptsToLoad);
69
+ </script>
70
+ </body>
71
+ </html>
.history/index_20241120000644.html ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!--
2
+ Copyright 2024 The Google Research Authors.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ -->
16
+
17
+ <!DOCTYPE html>
18
+ <html>
19
+ <head>
20
+ <meta charset=utf-8>
21
+ <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
22
+ <title>BlockMERF Viewer</title>
23
+ <style>
24
+ body {
25
+ font-family: Helvetica, "Helvetica Neue", sans-serif;
26
+ font-size: 18px;
27
+ background: #FFF;
28
+ padding: 20px; /* Picked to get an even nice resolution on iPhone 15 Pro */
29
+ margin: 0;
30
+ text-align: right;
31
+ }
32
+
33
+ #error {
34
+ display: none;
35
+ position: fixed;
36
+ top: 20px; left: 20px; right: 20px; bottom: 20px;
37
+ background: #444;
38
+ padding: 8px;
39
+ white-space: pre;
40
+ color: #fff;
41
+ font-family: monospace;
42
+ font-weight: bold;
43
+ }
44
+
45
+ #image-progress {
46
+ background: #000;
47
+ color: #FFF;
48
+ opacity: 0.75;
49
+ padding: 5px;
50
+ }
51
+
52
+ #Loading {
53
+ position: absolute;
54
+ top: 12px;
55
+ left: 90px;
56
+ }
57
+
58
+ #Loading h4 {
59
+ margin: 0px;
60
+ }
61
+
62
+ #loading-container {
63
+ width: 150px;
64
+ height: 150px;
65
+ padding: 0px;
66
+ margin: -40px 0 0 -40px;
67
+ position: absolute;
68
+ top: 50%;
69
+ left: 50%;
70
+ }
71
+
72
+ .loading-bgbox {
73
+ position: absolute;
74
+ width: 65px;
75
+ height: 65px;
76
+ background-color: #DDD;
77
+ width: 65px;
78
+ height: 65px;
79
+ }
80
+
81
+ #topleft {
82
+ top: 5px;
83
+ left: 5px;
84
+ }
85
+
86
+ #bottomleft {
87
+ bottom: 5px;
88
+ left: 5px;
89
+ }
90
+
91
+ #topright {
92
+ top: 5px;
93
+ right: 5px;
94
+ }
95
+
96
+ #bottomright {
97
+ bottom: 5px;
98
+ right: 5px;
99
+ }
100
+
101
+ #loading-indicator {
102
+ position: absolute;
103
+ top: 5px;
104
+ left: 5px;
105
+ width: 65px;
106
+ height: 65px;
107
+ background-color: #999;
108
+ animation-name: indicator;
109
+ animation-duration: 5s;
110
+ animation-iteration-count: infinite;
111
+ }
112
+
113
+ @keyframes indicator {
114
+ 0% {top: 5px; left: 5px; }
115
+ 25% {top: 5px; left: 80px; }
116
+ 50% {top: 80px; left: 80px; }
117
+ 75% {top: 80px; left: 5px; }
118
+ }
119
+
120
+
121
+ #benchmark-stats {
122
+ position: absolute;
123
+ top: 0px;
124
+ right: 0px;
125
+ display: none;
126
+ }
127
+
128
+ #shader-editor {
129
+ display: none;
130
+ margin-top: 10px;
131
+ margin-left: auto;
132
+ margin-right: auto;
133
+ }
134
+
135
+ </style>
136
+ <!-- Lien vers la feuille de style -->
137
+ </head>
138
+ <body>
139
+
140
+ <div id=error></div>
141
+
142
+ <!-- main content-->
143
+ <div id="viewspacecontainer">
144
+ <div id="Loading">
145
+ <h4>
146
+ <span id="image-progress">Loading images: 0/?</span>
147
+ </h4>
148
+ </div>
149
+ <textarea readonly id="benchmark-stats" rows="40" cols="40">
150
+ Click me to start benchmarking when the frame-rate is behaving reasonably.
151
+ </textarea>
152
+ <div id="loading-container">
153
+ <div id="topleft" class="loading-bgbox"></div>
154
+ <div id="bottomleft" class="loading-bgbox"></div>
155
+ <div id="topright" class="loading-bgbox"></div>
156
+ <div id="bottomright" class="loading-bgbox"></div>
157
+ <div id="loading-indicator"></div>
158
+ </div>
159
+ <div class=viewspace id="viewspace"></div>
160
+ </div>
161
+
162
+ <!-- shader editor -->
163
+ <textarea id="shader-editor" rows="50" cols="200"></textarea>
164
+
165
+ <!-- third party -->
166
+ <script src="https://unpkg.com/three@0.113.1/build/three.js"></script>
167
+ <script src="https://unpkg.com/three@0.113.1/examples/js/controls/OrbitControls.js"></script>
168
+ <script src="https://unpkg.com/three@0.113.1/examples/js/controls/PointerLockControls.js"></script>
169
+ <!-- <script src="https://unpkg.com/png-js@1.0.0/zlib.js"></script> -->
170
+ <!-- <script src="https://unpkg.com/png-js@1.0.0/png.js"></script> -->
171
+ <script src="https://unpkg.com/stats-js@1.0.1/build/stats.min.js"></script>
172
+ <script src="https://unpkg.com/file-saver@2.0.0-rc.2/dist/FileSaver.min.js"></script>
173
+
174
+ <!-- Use if you've downloaded these scripts locally. -->
175
+ <!-- <script src="deps/three.js"></script> -->
176
+ <!-- <script src="deps/OrbitControls.js"></script> -->
177
+ <!-- <script src="deps/PointerLockControls.js"></script> -->
178
+ <script type="module" src="src/deps/zlib.js"></script>
179
+ <script type="module" src="src/deps/png.js"></script>
180
+ <!-- type="module" <script type="module" src="deps/stats.min.js"></script> type="module" -->
181
+
182
+ <!-- type="module" own type="module" code-->
183
+ <script type="module" src="src/scene_spec.js"></script>
184
+ <script type="module" src="src/fetch_asset.js"></script>
185
+ <script type="module" src="src/create_texture.js"></script>
186
+ <script type="module" src="src/prepare_payload.js"></script>
187
+ <script type="module" src="src/populate_texture.js"></script>
188
+ <script type="module" src="src/texture_manager.js"></script>
189
+ <script type="module" src="src/worker_pool.js"></script>
190
+ <script type="module" src="src/globals.js"></script>
191
+ <script type="module" src="src/utils.js"></script>
192
+ <script type="module" src="src/progressive.js"></script>
193
+ <script type="module" src="src/viewdependency.js"></script>
194
+ <script type="module" src="src/defaultposes.js"></script>
195
+ <script type="module" src="src/input.js"></script>
196
+ <script type="module" src="src/benchmark.js"></script>
197
+ <script type="module" src="src/index.js"></script>
198
+ </body>
199
+ </html>