@@ -3,17 +3,16 @@ import {
3
3
Directive ,
4
4
EmbeddedViewRef ,
5
5
Injector ,
6
- Signal ,
6
+ ResourceRef ,
7
7
TemplateRef ,
8
8
ViewContainerRef ,
9
9
computed ,
10
10
effect ,
11
11
inject ,
12
12
input ,
13
- output ,
14
13
signal ,
15
14
} from '@angular/core' ;
16
- import { injectTexture } from 'angular-three-soba/loaders' ;
15
+ import { injectTexture , textureResource } from 'angular-three-soba/loaders' ;
17
16
import { assertInjector } from 'ngxtension/assert-injector' ;
18
17
import * as THREE from 'three' ;
19
18
@@ -26,6 +25,10 @@ interface NgtsNormalTextureSettings {
26
25
offset ?: number [ ] ;
27
26
}
28
27
28
+ /**
29
+ * @deprecated Use normalTexture instead. Will be removed in v5.0.0
30
+ * @since v4.0.0
31
+ */
29
32
export function injectNormalTexture (
30
33
id : ( ) => string | number = ( ) => 0 ,
31
34
{
@@ -79,14 +82,68 @@ export function injectNormalTexture(
79
82
} ) ;
80
83
}
81
84
85
+ export function normalTextureResource (
86
+ id : ( ) => string | number = ( ) => 0 ,
87
+ {
88
+ settings = ( ) => ( { } ) ,
89
+ onLoad,
90
+ injector,
91
+ } : { settings ?: ( ) => NgtsNormalTextureSettings ; onLoad ?: ( texture : THREE . Texture ) => void ; injector ?: Injector } ,
92
+ ) {
93
+ return assertInjector ( normalTextureResource , injector , ( ) => {
94
+ const normalList = signal < Record < string , string > > ( { } ) ;
95
+
96
+ fetch ( LIST_URL )
97
+ . then ( ( res ) => res . json ( ) )
98
+ . then ( ( list ) => {
99
+ normalList . set ( list ) ;
100
+ } ) ;
101
+
102
+ const DEFAULT_NORMAL = computed ( ( ) => normalList ( ) [ 0 ] ) ;
103
+ const numTot = computed ( ( ) => Object . keys ( normalList ( ) ) . length ) ;
104
+
105
+ const fileHash = computed ( ( ) => {
106
+ const idValue = id ( ) ;
107
+ if ( typeof idValue === 'string' ) {
108
+ return idValue ;
109
+ }
110
+
111
+ if ( typeof idValue === 'number' ) {
112
+ return normalList ( ) [ idValue ] ;
113
+ }
114
+
115
+ return null ;
116
+ } ) ;
117
+
118
+ const imageName = computed ( ( ) => fileHash ( ) || DEFAULT_NORMAL ( ) ) ;
119
+ const url = computed ( ( ) => `${ NORMAL_ROOT } /normals/${ imageName ( ) } ` ) ;
120
+
121
+ const resource = textureResource ( url , { onLoad } ) ;
122
+
123
+ effect ( ( ) => {
124
+ if ( ! resource . hasValue ( ) ) return ;
125
+
126
+ const texture = resource . value ( ) ;
127
+ const { anisotropy = 1 , repeat = [ 1 , 1 ] , offset = [ 0 , 0 ] } = settings ( ) ;
128
+
129
+ texture . wrapS = texture . wrapT = THREE . RepeatWrapping ;
130
+ texture . repeat = new THREE . Vector2 ( repeat [ 0 ] , repeat [ 1 ] ) ;
131
+ texture . offset = new THREE . Vector2 ( offset [ 0 ] , offset [ 1 ] ) ;
132
+ texture . anisotropy = anisotropy ;
133
+ } ) ;
134
+
135
+ return { url, resource, numTot } ;
136
+ } ) ;
137
+ }
138
+
82
139
export interface NgtsNormalTextureOptions extends NgtsNormalTextureSettings {
83
140
id ?: number | string ;
84
141
}
85
142
86
143
@Directive ( { selector : 'ng-template[normalTexture]' } )
87
144
export class NgtsNormalTexture {
88
145
normalTexture = input < NgtsNormalTextureOptions > ( ) ;
89
- normalTextureLoaded = output < THREE . Texture [ ] > ( ) ;
146
+ normalTextureLoaded = input < ( texture : THREE . Texture ) => void > ( ) ;
90
147
91
148
private template = inject ( TemplateRef ) ;
92
149
private vcr = inject ( ViewContainerRef ) ;
@@ -97,16 +154,16 @@ export class NgtsNormalTexture {
97
154
return settings ;
98
155
} ) ;
99
156
100
- private ref ?: EmbeddedViewRef < { $implicit : Signal < THREE . Texture | null > } > ;
157
+ private ref ?: EmbeddedViewRef < { $implicit : ResourceRef < THREE . Texture | undefined > } > ;
101
158
102
159
constructor ( ) {
103
- const { texture } = injectNormalTexture ( this . id , {
160
+ const { resource } = normalTextureResource ( this . id , {
104
161
settings : this . settings ,
105
- onLoad : this . normalTextureLoaded . emit . bind ( this . normalTextureLoaded ) ,
162
+ onLoad : this . normalTextureLoaded ( ) ,
106
163
} ) ;
107
164
108
165
effect ( ( ) => {
109
- this . ref = this . vcr . createEmbeddedView ( this . template , { $implicit : texture } ) ;
166
+ this . ref = this . vcr . createEmbeddedView ( this . template , { $implicit : resource } ) ;
110
167
this . ref . detectChanges ( ) ;
111
168
} ) ;
112
169
@@ -118,7 +175,7 @@ export class NgtsNormalTexture {
118
175
static ngTemplateContextGuard (
119
176
_ : NgtsNormalTexture ,
120
177
ctx : unknown ,
121
- ) : ctx is { $implicit : Signal < THREE . Texture | null > } {
178
+ ) : ctx is { $implicit : ResourceRef < THREE . Texture | undefined > } {
122
179
return true ;
123
180
}
124
181
}
0 commit comments