Spaces:
Sleeping
Sleeping
Natha1627
commited on
Commit
·
3b6bb5e
1
Parent(s):
c6f625c
Initial commit
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .env +1 -0
- .history/.env_20241115180340 +1 -0
- .history/.env_20241204120505 +1 -0
- .history/.env_20241204120506 +1 -0
- .history/.env_20241204120509 +1 -0
- .history/.env_20241204120512 +1 -0
- .history/.env_20241204120522 +1 -0
- .history/.env_20241204120639 +1 -0
- .history/Dockerfile_20241204120405 +0 -0
- .history/Dockerfile_20241204120409 +29 -0
- .history/Dockerfile_20241204120738 +29 -0
- .history/Dockerfile_20241204120940 +29 -0
- .history/Dockerfile_20241204121832 +29 -0
- .history/combined.min_20241119235702.js +1 -0
- .history/combined.min_20241120000008.js +3 -0
- .history/combined.min_20241120000010.js +2 -0
- .history/combined_20241201141501.js +0 -0
- .history/combined_20241201141504.js +0 -0
- .history/copyslices.worker_20241118132102.js +129 -0
- .history/copyslices.worker_20241204081957.js +129 -0
- .history/copyslices.worker_20241204081958.js +129 -0
- .history/copyslices.worker_20241204082633.js +129 -0
- .history/copyslices.worker_20241204114216.js +129 -0
- .history/copyslices.worker_20241204114218.js +129 -0
- .history/fetch_ex_bbox_20241120090937.js +0 -0
- .history/fetch_ex_bbox_20241120090941.js +108 -0
- .history/fetch_ex_bbox_20241120093705.js +133 -0
- .history/fetch_ex_bbox_20241120093930.js +136 -0
- .history/form/index_20241119001656.html +71 -0
- .history/form/index_20241120180531.html +67 -0
- .history/form/index_20241120180543.html +66 -0
- .history/globals_20241204111341.js +186 -0
- .history/globals_20241204114937.js +186 -0
- .history/globals_20241204114940.js +186 -0
- .history/index_20241118162737.js +549 -0
- .history/index_20241119000624.html +132 -0
- .history/index_20241119234025.html +129 -0
- .history/index_20241119234048.html +100 -0
- .history/index_20241119234054.html +95 -0
- .history/index_20241119234122.html +95 -0
- .history/index_20241119234131.html +90 -0
- .history/index_20241119234135.html +90 -0
- .history/index_20241119235124.html +47 -0
- .history/index_20241119235326.html +90 -0
- .history/index_20241119235341.html +71 -0
- .history/index_20241119235343.html +71 -0
- .history/index_20241119235345.html +71 -0
- .history/index_20241119235353.html +71 -0
- .history/index_20241119235401.html +71 -0
- .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>
|