@@ -4,6 +4,11 @@ import type {
44 LLGLTFMaterialEntry ,
55 LLGLTFTextureInfo ,
66} from './LLGLTFMaterialData' ;
7+ import { LLSD } from './llsd/LLSD' ;
8+ import { LLSDInteger } from './llsd/LLSDInteger' ;
9+ import { LLSDMap } from './llsd/LLSDMap' ;
10+ import { LLSDReal } from './llsd/LLSDReal' ;
11+ import type { LLSDType } from './llsd/LLSDType' ;
712import { UUID } from './UUID' ;
813
914export interface LLGLTFTextureTransformOverride
@@ -25,6 +30,118 @@ export class LLGLTFMaterialOverride
2530 public doubleSided ?: boolean ;
2631 public textureTransforms ?: ( LLGLTFTextureTransformOverride | null ) [ ] ;
2732
33+ public static fromStoredMaterial ( data : string ) : LLGLTFMaterialOverride
34+ {
35+ try
36+ {
37+ return LLGLTFMaterialOverride . fromFullMaterialJSON ( data ) ;
38+ }
39+ catch ( _error : unknown )
40+ {
41+ return LLGLTFMaterialOverride . fromOverrideLLSDNotation ( data ) ;
42+ }
43+ }
44+
45+ public static fromOverrideLLSDNotation ( notation : string ) : LLGLTFMaterialOverride
46+ {
47+ const over = new LLGLTFMaterialOverride ( ) ;
48+ const parsed = LLSD . parseNotation ( notation ) ;
49+ if ( ! ( parsed instanceof LLSDMap ) )
50+ {
51+ return over ;
52+ }
53+
54+ const tex = parsed . get ( 'tex' ) ;
55+ if ( Array . isArray ( tex ) )
56+ {
57+ for ( let i = 0 ; i < tex . length ; i ++ )
58+ {
59+ const entry = tex [ i ] ;
60+ if ( entry instanceof UUID && ! entry . isZero ( ) )
61+ {
62+ over . setTexture ( i , entry . toString ( ) ) ;
63+ }
64+ }
65+ }
66+
67+ const baseColor = LLGLTFMaterialOverride . llsdNumberArray ( parsed . get ( 'bc' ) ) ;
68+ if ( baseColor !== undefined && baseColor . length === 4 )
69+ {
70+ over . baseColor = baseColor ;
71+ }
72+
73+ const emissive = LLGLTFMaterialOverride . llsdNumberArray ( parsed . get ( 'ec' ) ) ;
74+ if ( emissive !== undefined )
75+ {
76+ over . emissiveFactor = emissive ;
77+ }
78+
79+ const metallic = LLGLTFMaterialOverride . llsdNumber ( parsed . get ( 'mf' ) ) ;
80+ if ( metallic !== undefined )
81+ {
82+ over . metallicFactor = metallic ;
83+ }
84+
85+ const roughness = LLGLTFMaterialOverride . llsdNumber ( parsed . get ( 'rf' ) ) ;
86+ if ( roughness !== undefined )
87+ {
88+ over . roughnessFactor = roughness ;
89+ }
90+
91+ const alphaMode = LLGLTFMaterialOverride . llsdNumber ( parsed . get ( 'am' ) ) ;
92+ if ( alphaMode !== undefined )
93+ {
94+ over . alphaMode = alphaMode ;
95+ }
96+
97+ const alphaCutoff = LLGLTFMaterialOverride . llsdNumber ( parsed . get ( 'ac' ) ) ;
98+ if ( alphaCutoff !== undefined )
99+ {
100+ over . alphaCutoff = alphaCutoff ;
101+ }
102+
103+ const doubleSided = parsed . get ( 'ds' ) ;
104+ if ( typeof doubleSided === 'boolean' )
105+ {
106+ over . doubleSided = doubleSided ;
107+ }
108+
109+ const transforms = parsed . get ( 'ti' ) ;
110+ if ( Array . isArray ( transforms ) )
111+ {
112+ for ( let i = 0 ; i < transforms . length ; i ++ )
113+ {
114+ const entry = transforms [ i ] ;
115+ if ( ! ( entry instanceof LLSDMap ) )
116+ {
117+ continue ;
118+ }
119+ const transform : LLGLTFTextureTransformOverride = { } ;
120+ const offset = LLGLTFMaterialOverride . llsdNumberArray ( entry . get ( 'o' ) ) ;
121+ if ( offset !== undefined )
122+ {
123+ transform . offset = offset ;
124+ }
125+ const scale = LLGLTFMaterialOverride . llsdNumberArray ( entry . get ( 's' ) ) ;
126+ if ( scale !== undefined )
127+ {
128+ transform . scale = scale ;
129+ }
130+ const rotation = LLGLTFMaterialOverride . llsdNumber ( entry . get ( 'r' ) ) ;
131+ if ( rotation !== undefined )
132+ {
133+ transform . rotation = rotation ;
134+ }
135+ if ( Object . keys ( transform ) . length > 0 )
136+ {
137+ over . setTransform ( i , transform ) ;
138+ }
139+ }
140+ }
141+
142+ return over ;
143+ }
144+
28145 public static fromFullMaterialJSON ( json : string ) : LLGLTFMaterialOverride
29146 {
30147 const obj = JSON . parse ( json ) as LLGLTFMaterialData ;
@@ -400,4 +517,36 @@ export class LLGLTFMaterialOverride
400517 }
401518 this . textureTransforms [ idx ] = trans ;
402519 }
520+
521+ private static llsdNumber ( value : LLSDType | undefined ) : number | undefined
522+ {
523+ if ( value instanceof LLSDInteger || value instanceof LLSDReal )
524+ {
525+ return value . valueOf ( ) ;
526+ }
527+ if ( typeof value === 'number' )
528+ {
529+ return value ;
530+ }
531+ return undefined ;
532+ }
533+
534+ private static llsdNumberArray ( value : LLSDType | undefined ) : number [ ] | undefined
535+ {
536+ if ( ! Array . isArray ( value ) )
537+ {
538+ return undefined ;
539+ }
540+ const result : number [ ] = [ ] ;
541+ for ( const entry of value )
542+ {
543+ const num = LLGLTFMaterialOverride . llsdNumber ( entry ) ;
544+ if ( num === undefined )
545+ {
546+ return undefined ;
547+ }
548+ result . push ( num ) ;
549+ }
550+ return result ;
551+ }
403552}
0 commit comments