66 Measurer ,
77 type Parsed ,
88} from 'typed-binary' ;
9- import { CallableImpl } from '../callable' ;
109import { RecursiveDataTypeError } from '../errors' ;
1110import { roundUp } from '../mathUtils' ;
1211import type { TgpuData } from '../types' ;
@@ -17,48 +16,72 @@ import { vec2f, vec3f, vec4f, type vecBase } from './vector';
1716// Implementation
1817// --------------
1918
20- interface MatSchemaOptions < T , TVec extends vecBase > {
19+ interface MatSchemaOptions < ValueType , ColumnType extends vecBase > {
2120 label : string ;
22- columnType : TgpuData < TVec > ;
21+ columnType : TgpuData < ColumnType > ;
2322 rows : number ;
2423 columns : number ;
25- makeFromColumnVectors ( ...columns : TVec [ ] ) : T ;
26- makeFromElements ( ...elements : number [ ] ) : T ;
24+ makeFromColumnVectors ( ...columns : ColumnType [ ] ) : ValueType ;
25+ makeFromElements ( ...elements : number [ ] ) : ValueType ;
2726}
2827
29- class MatSchemaImpl < T extends matBase < TColumn > , TColumn extends vecBase >
30- extends CallableImpl < ( number | TColumn ) [ ] , T >
31- implements TgpuData < T >
32- {
33- public readonly __unwrapped ! : T ;
34-
35- private readonly _columnType : TgpuData < TColumn > ;
36- private readonly _rows : number ;
37- private readonly _columns : number ;
38- private readonly _makeFromColumnVectors : ( ...columns : TColumn [ ] ) => T ;
39- private readonly _makeFromElements : ( ...elements : number [ ] ) => T ;
40-
41- public readonly byteAlignment : number ;
42- public readonly size : number ;
43- public readonly label : string ;
44-
45- constructor ( options : MatSchemaOptions < T , TColumn > ) {
46- super ( ) ;
47- this . _columnType = options . columnType ;
48- this . _rows = options . rows ;
49- this . _columns = options . columns ;
50- this . label = options . label ;
51- this . _makeFromColumnVectors = options . makeFromColumnVectors ;
52- this . _makeFromElements = options . makeFromElements ;
53-
54- this . byteAlignment = this . _columnType . byteAlignment ;
55- this . size = roundUp (
56- this . _columnType . size * this . _columns ,
57- this . byteAlignment ,
58- ) ;
59- }
28+ type MatSchema <
29+ ValueType extends matBase < ColumnType > ,
30+ ColumnType extends vecBase ,
31+ > = TgpuData < ValueType > & ( ( ...args : ( number | ColumnType ) [ ] ) => ValueType ) ;
32+
33+ function createMatSchema <
34+ ValueType extends matBase < ColumnType > ,
35+ ColumnType extends vecBase ,
36+ > (
37+ options : MatSchemaOptions < ValueType , ColumnType > ,
38+ ) : MatSchema < ValueType , ColumnType > {
39+ const MatSchema : TgpuData < ValueType > = {
40+ // Type-token, not available at runtime.
41+ __unwrapped : undefined as unknown as ValueType ,
42+
43+ label : options . label ,
44+ byteAlignment : options . columnType . byteAlignment ,
45+ size : roundUp (
46+ options . columnType . size * options . columns ,
47+ options . columnType . byteAlignment ,
48+ ) ,
49+
50+ resolveReferences ( ) {
51+ throw new RecursiveDataTypeError ( ) ;
52+ } ,
53+
54+ write ( output : ISerialOutput , value : Parsed < ValueType > ) : void {
55+ for ( const col of value . columns ( ) ) {
56+ options . columnType . write ( output , col as Parsed < ColumnType > ) ;
57+ }
58+ } ,
59+
60+ read ( input : ISerialInput ) : Parsed < ValueType > {
61+ const columns = new Array ( options . columns ) as ColumnType [ ] ;
62+
63+ for ( let c = 0 ; c < options . columns ; ++ c ) {
64+ columns [ c ] = options . columnType . read ( input ) as ColumnType ;
65+ }
66+
67+ return options . makeFromColumnVectors ( ...columns ) as Parsed < ValueType > ;
68+ } ,
6069
61- _call ( ...args : ( number | TColumn ) [ ] ) : T {
70+ measure ( _value : MaxValue , measurer : IMeasurer = new Measurer ( ) ) : IMeasurer {
71+ alignIO ( measurer , this . byteAlignment ) ;
72+ return measurer . add ( this . size ) ;
73+ } ,
74+
75+ seekProperty ( ) {
76+ throw new Error ( 'Method not implemented.' ) ;
77+ } ,
78+
79+ resolve ( ) : string {
80+ return options . label ;
81+ } ,
82+ } ;
83+
84+ const construct = ( ...args : ( number | ColumnType ) [ ] ) : ValueType => {
6285 const elements : number [ ] = [ ] ;
6386
6487 for ( const arg of args ) {
@@ -70,45 +93,14 @@ class MatSchemaImpl<T extends matBase<TColumn>, TColumn extends vecBase>
7093 }
7194
7295 // Fill the rest with zeros
73- for ( let i = elements . length ; i < this . _columns * this . _rows ; ++ i ) {
96+ for ( let i = elements . length ; i < options . columns * options . rows ; ++ i ) {
7497 elements . push ( 0 ) ;
7598 }
7699
77- return this . _makeFromElements ( ...elements ) ;
78- }
79-
80- resolveReferences ( ) : void {
81- throw new RecursiveDataTypeError ( ) ;
82- }
83-
84- write ( output : ISerialOutput , value : Parsed < T > ) : void {
85- for ( const col of value . columns ( ) ) {
86- this . _columnType . write ( output , col as Parsed < TColumn > ) ;
87- }
88- }
89-
90- read ( input : ISerialInput ) : Parsed < T > {
91- const columns = new Array ( this . _columns ) as TColumn [ ] ;
100+ return options . makeFromElements ( ...elements ) ;
101+ } ;
92102
93- for ( let c = 0 ; c < this . _columns ; ++ c ) {
94- columns [ c ] = this . _columnType . read ( input ) as TColumn ;
95- }
96-
97- return this . _makeFromColumnVectors ( ...columns ) as Parsed < T > ;
98- }
99-
100- measure ( _value : MaxValue , measurer : IMeasurer = new Measurer ( ) ) : IMeasurer {
101- alignIO ( measurer , this . byteAlignment ) ;
102- return measurer . add ( this . size ) ;
103- }
104-
105- seekProperty ( ) : null {
106- throw new Error ( 'Method not implemented.' ) ;
107- }
108-
109- resolve ( ) : string {
110- return this . label ;
111- }
103+ return Object . assign ( construct , MatSchema ) ;
112104}
113105
114106interface matBase < TColumn > {
@@ -308,15 +300,15 @@ export type Mat2x2f = TgpuData<mat2x2f> &
308300 ( ( ...columns : vec2f [ ] ) => mat2x2f ) &
309301 ( ( ) => mat2x2f ) ;
310302
311- export const mat2x2f = new MatSchemaImpl ( {
303+ export const mat2x2f = createMatSchema ( {
312304 label : 'mat2x2f' ,
313305 columnType : vec2f ,
314306 rows : 2 ,
315307 columns : 2 ,
316308 makeFromColumnVectors : ( ...columns : [ vec2f , vec2f ] ) =>
317309 new mat2x2fImpl ( ...columns [ 0 ] , ...columns [ 1 ] ) ,
318310 makeFromElements : ( ...elements : number [ ] ) => new mat2x2fImpl ( ...elements ) ,
319- } ) as unknown as Mat2x2f ;
311+ } ) as Mat2x2f ;
320312
321313export interface mat3x3 < TColumn > extends matBase < TColumn > {
322314 [ 0 ] : TColumn ;
@@ -332,7 +324,7 @@ export type Mat3x3f = TgpuData<mat3x3f> &
332324 ( ( ...columns : vec3f [ ] ) => mat3x3f ) &
333325 ( ( ) => mat3x3f ) ;
334326
335- export const mat3x3f = new MatSchemaImpl ( {
327+ export const mat3x3f = createMatSchema ( {
336328 label : 'mat3x3f' ,
337329 columnType : vec3f ,
338330 rows : 3 ,
@@ -341,7 +333,7 @@ export const mat3x3f = new MatSchemaImpl({
341333 return new mat3x3fImpl ( ...v0 , ...v1 , ...v2 ) ;
342334 } ,
343335 makeFromElements : ( ...elements : number [ ] ) => new mat3x3fImpl ( ...elements ) ,
344- } ) as unknown as Mat3x3f ;
336+ } ) as Mat3x3f ;
345337
346338export interface mat4x4 < TColumn > extends matBase < TColumn > {
347339 [ 0 ] : TColumn ;
@@ -358,7 +350,7 @@ export type Mat4x4f = TgpuData<mat4x4f> &
358350 ( ( ...columns : vec4f [ ] ) => mat4x4f ) &
359351 ( ( ) => mat4x4f ) ;
360352
361- export const mat4x4f = new MatSchemaImpl ( {
353+ export const mat4x4f = createMatSchema ( {
362354 label : 'mat4x4f' ,
363355 columnType : vec4f ,
364356 rows : 4 ,
@@ -367,4 +359,4 @@ export const mat4x4f = new MatSchemaImpl({
367359 return new mat4x4fImpl ( ...v0 , ...v1 , ...v2 , ...v3 ) ;
368360 } ,
369361 makeFromElements : ( ...elements : number [ ] ) => new mat4x4fImpl ( ...elements ) ,
370- } ) as unknown as Mat4x4f ;
362+ } ) as Mat4x4f ;
0 commit comments