@@ -56,6 +56,11 @@ namespace gdjs {
5656 */
5757 private _loadedThreeTextures : Hashtable < THREE . Texture > ;
5858 private _loadedThreeMaterials = new ThreeMaterialCache ( ) ;
59+ private _loadedThreeCubeTextures = new Map < string , THREE . CubeTexture > ( ) ;
60+ private _loadedThreeCubeTextureKeysByResourceName = new ArrayMap <
61+ string ,
62+ string
63+ > ( ) ;
5964
6065 private _diskTextures = new Map < float , PIXI . Texture > ( ) ;
6166 private _rectangleTextures = new Map < string , PIXI . Texture > ( ) ;
@@ -181,7 +186,25 @@ namespace gdjs {
181186 if ( loadedThreeTexture ) {
182187 return loadedThreeTexture ;
183188 }
189+ const image = this . _getImageSource ( resourceName ) ;
184190
191+ const threeTexture = new THREE . Texture ( image ) ;
192+ threeTexture . magFilter = THREE . LinearFilter ;
193+ threeTexture . minFilter = THREE . LinearFilter ;
194+ threeTexture . wrapS = THREE . RepeatWrapping ;
195+ threeTexture . wrapT = THREE . RepeatWrapping ;
196+ threeTexture . colorSpace = THREE . SRGBColorSpace ;
197+ threeTexture . needsUpdate = true ;
198+
199+ const resource = this . _getImageResource ( resourceName ) ;
200+
201+ applyThreeTextureSettings ( threeTexture , resource ) ;
202+ this . _loadedThreeTextures . put ( resourceName , threeTexture ) ;
203+
204+ return threeTexture ;
205+ }
206+
207+ private _getImageSource ( resourceName : string ) : HTMLImageElement {
185208 // Texture is not loaded, load it now from the PixiJS texture.
186209 // TODO (3D) - optimization: don't load the PixiJS Texture if not used by PixiJS.
187210 // TODO (3D) - optimization: Ideally we could even share the same WebGL texture.
@@ -198,21 +221,86 @@ namespace gdjs {
198221 `Can't load texture for resource "${ resourceName } " as it's not an image.`
199222 ) ;
200223 }
224+ return image ;
225+ }
201226
202- const threeTexture = new THREE . Texture ( image ) ;
203- threeTexture . magFilter = THREE . LinearFilter ;
204- threeTexture . minFilter = THREE . LinearFilter ;
205- threeTexture . wrapS = THREE . RepeatWrapping ;
206- threeTexture . wrapT = THREE . RepeatWrapping ;
207- threeTexture . colorSpace = THREE . SRGBColorSpace ;
208- threeTexture . needsUpdate = true ;
209-
210- const resource = this . _getImageResource ( resourceName ) ;
227+ /**
228+ * Return the three.js texture associated to the specified resource name.
229+ * Returns a placeholder texture if not found.
230+ * @param xPositiveResourceName The name of the resource
231+ * @returns The requested cube texture, or a placeholder if not found.
232+ */
233+ getThreeCubeTexture (
234+ xPositiveResourceName : string ,
235+ xNegativeResourceName : string ,
236+ yPositiveResourceName : string ,
237+ yNegativeResourceName : string ,
238+ zPositiveResourceName : string ,
239+ zNegativeResourceName : string
240+ ) : THREE . CubeTexture {
241+ const key =
242+ xPositiveResourceName +
243+ '|' +
244+ xNegativeResourceName +
245+ '|' +
246+ yPositiveResourceName +
247+ '|' +
248+ yNegativeResourceName +
249+ '|' +
250+ zPositiveResourceName +
251+ '|' +
252+ zNegativeResourceName ;
253+ const loadedThreeTexture = this . _loadedThreeCubeTextures . get ( key ) ;
254+ if ( loadedThreeTexture ) {
255+ return loadedThreeTexture ;
256+ }
211257
212- applyThreeTextureSettings ( threeTexture , resource ) ;
213- this . _loadedThreeTextures . put ( resourceName , threeTexture ) ;
258+ const cubeTexture = new THREE . CubeTexture ( ) ;
259+ // Faces on X axis need to be swapped.
260+ cubeTexture . images [ 0 ] = this . _getImageSource ( xNegativeResourceName ) ;
261+ cubeTexture . images [ 1 ] = this . _getImageSource ( xPositiveResourceName ) ;
262+ // Faces on Y keep the same order.
263+ cubeTexture . images [ 2 ] = this . _getImageSource ( yPositiveResourceName ) ;
264+ cubeTexture . images [ 3 ] = this . _getImageSource ( yNegativeResourceName ) ;
265+ // Faces on Z keep the same order.
266+ cubeTexture . images [ 4 ] = this . _getImageSource ( zPositiveResourceName ) ;
267+ cubeTexture . images [ 5 ] = this . _getImageSource ( zNegativeResourceName ) ;
268+ // The images also need to be mirrored horizontally by users.
269+
270+ cubeTexture . magFilter = THREE . LinearFilter ;
271+ cubeTexture . minFilter = THREE . LinearFilter ;
272+ cubeTexture . colorSpace = THREE . SRGBColorSpace ;
273+ cubeTexture . needsUpdate = true ;
274+
275+ const resource = this . _getImageResource ( xPositiveResourceName ) ;
276+ applyThreeTextureSettings ( cubeTexture , resource ) ;
277+ this . _loadedThreeCubeTextures . set ( key , cubeTexture ) ;
278+ this . _loadedThreeCubeTextureKeysByResourceName . add (
279+ xPositiveResourceName ,
280+ key
281+ ) ;
282+ this . _loadedThreeCubeTextureKeysByResourceName . add (
283+ xNegativeResourceName ,
284+ key
285+ ) ;
286+ this . _loadedThreeCubeTextureKeysByResourceName . add (
287+ yPositiveResourceName ,
288+ key
289+ ) ;
290+ this . _loadedThreeCubeTextureKeysByResourceName . add (
291+ yNegativeResourceName ,
292+ key
293+ ) ;
294+ this . _loadedThreeCubeTextureKeysByResourceName . add (
295+ zPositiveResourceName ,
296+ key
297+ ) ;
298+ this . _loadedThreeCubeTextureKeysByResourceName . add (
299+ zNegativeResourceName ,
300+ key
301+ ) ;
214302
215- return threeTexture ;
303+ return cubeTexture ;
216304 }
217305
218306 /**
@@ -482,6 +570,11 @@ namespace gdjs {
482570 for ( const threeTexture of threeTextures ) {
483571 threeTexture . dispose ( ) ;
484572 }
573+ for ( const cubeTexture of this . _loadedThreeCubeTextures . values ( ) ) {
574+ cubeTexture . dispose ( ) ;
575+ }
576+ this . _loadedThreeCubeTextures . clear ( ) ;
577+ this . _loadedThreeCubeTextureKeysByResourceName . clear ( ) ;
485578
486579 this . _loadedThreeMaterials . disposeAll ( ) ;
487580
@@ -528,12 +621,51 @@ namespace gdjs {
528621 }
529622
530623 this . _loadedThreeMaterials . dispose ( resourceName ) ;
624+
625+ const cubeTextureKeys =
626+ this . _loadedThreeCubeTextureKeysByResourceName . getValuesFor (
627+ resourceName
628+ ) ;
629+ if ( cubeTextureKeys ) {
630+ for ( const cubeTextureKey of cubeTextureKeys ) {
631+ const cubeTexture = this . _loadedThreeCubeTextures . get ( cubeTextureKey ) ;
632+ if ( cubeTexture ) {
633+ cubeTexture . dispose ( ) ;
634+ this . _loadedThreeCubeTextures . delete ( cubeTextureKey ) ;
635+ }
636+ }
637+ }
638+ }
639+ }
640+
641+ class ArrayMap < K , V > {
642+ map = new Map < K , Array < V > > ( ) ;
643+
644+ getValuesFor ( key : K ) : Array < V > | undefined {
645+ return this . map . get ( key ) ;
646+ }
647+
648+ add ( key : K , value : V ) : void {
649+ let values = this . map . get ( key ) ;
650+ if ( ! values ) {
651+ values = [ ] ;
652+ this . map . set ( key , values ) ;
653+ }
654+ values . push ( value ) ;
655+ }
656+
657+ deleteValuesFor ( key : K ) : void {
658+ this . map . delete ( key ) ;
659+ }
660+
661+ clear ( ) : void {
662+ this . map . clear ( ) ;
531663 }
532664 }
533665
534666 class ThreeMaterialCache {
535667 private _flaggedMaterials = new Map < string , THREE . Material > ( ) ;
536- private _materialFlaggedKeys = new Map < string , Array < string > > ( ) ;
668+ private _materialFlaggedKeys = new ArrayMap < string , string > ( ) ;
537669
538670 /**
539671 * Return the three.js material associated to the specified resource name
@@ -584,12 +716,7 @@ namespace gdjs {
584716 forceBasicMaterial ? 1 : 0
585717 } |${ vertexColors ? 1 : 0 } `;
586718 this . _flaggedMaterials . set ( cacheKey , material ) ;
587- let flaggedKeys = this . _materialFlaggedKeys . get ( resourceName ) ;
588- if ( ! flaggedKeys ) {
589- flaggedKeys = [ ] ;
590- this . _materialFlaggedKeys . set ( resourceName , flaggedKeys ) ;
591- }
592- flaggedKeys . push ( cacheKey ) ;
719+ this . _materialFlaggedKeys . add ( resourceName , cacheKey ) ;
593720 }
594721
595722 /**
@@ -598,7 +725,7 @@ namespace gdjs {
598725 * @param resourceName The name of the resource
599726 */
600727 dispose ( resourceName : string ) : void {
601- const flaggedKeys = this . _materialFlaggedKeys . get ( resourceName ) ;
728+ const flaggedKeys = this . _materialFlaggedKeys . getValuesFor ( resourceName ) ;
602729 if ( flaggedKeys ) {
603730 for ( const flaggedKey of flaggedKeys ) {
604731 const threeMaterial = this . _flaggedMaterials . get ( flaggedKey ) ;
@@ -608,7 +735,7 @@ namespace gdjs {
608735 this . _flaggedMaterials . delete ( flaggedKey ) ;
609736 }
610737 }
611- this . _materialFlaggedKeys . delete ( resourceName ) ;
738+ this . _materialFlaggedKeys . deleteValuesFor ( resourceName ) ;
612739 }
613740
614741 /**
0 commit comments