import * as Specification from "../specification" ; import { getBindingValue , BindingPrimitive , types , Type } from "./types" ; /** Data structure for a texture */ export interface TextureData { width : number ; height : number ; numberComponents : number ; type : "f32" | "u8" | "HTMLImageElement" | "HTMLCanvasElement" ; data : Float32Array | Uint8Array | Uint8ClampedArray | HTMLCanvasElement | HTMLImageElement ; dimensions : number ; } /** Texture data binding */ export abstract class TextureBinding { public abstract getTextureData ( ) ; } export type ArrayBindingFunction = ( datum : any , index : number , data : any [ ] ) => BindingPrimitive ; export class Array extends TextureBinding { private _data : any [ ] = null ; private _valueFunction : ArrayBindingFunction = null ; private _dirty = false ; private _textureData : TextureData = null ; public getTextureData ( ) { if ( this . _dirty ) { let values = this . _data . map ( this . _valueFunction ) . map ( getBindingValue ) ; if ( values . length == 0 ) { this . _textureData = null ; } else { let array ; let numberComponents ; if ( typeof ( values [ 0 ] ) == "number" ) { numberComponents = 1 ; array = new Float32Array ( values . length * 4 ) ; for ( let i = 0 ; i < values . length ; i ++ ) { array [ i * 4 ] = values [ i ] as number ; } } else { numberComponents = ( values [ 0 ] as number [ ] ) . length ; array = new Float32Array ( values . length * 4 ) ; let offset = 0 ; for ( let i = 0 ; i < values . length ; i ++ ) { let v = values [ i ] as number [ ] ; for ( let j = 0 ; j < numberComponents ; j ++ ) { array [ offset ++ ] = v [ j ] ; } offset += 4 - numberComponents ; } } this . _textureData = { width : this . _data . length , height : 1 , dimensions : 1 , type : "f32" , numberComponents : numberComponents , data : array } ; } } return this . _textureData ; } public data ( ) ; public data ( data ) ; public data ( data ? ) { if ( data != null ) { this . _data = data ; this . _dirty = true ; return this ; } else { return this . _data ; } } public value ( ) ; public value ( func ) ; public value ( func ? ) { if ( func != null ) { this . _valueFunction = func ; this . _dirty = true ; return this ; } else { return this . _valueFunction ; } } } export class Image extends TextureBinding { _data : TextureData = null ; setImage ( image ) { this . _data = { width : image . width , height : image . height , numberComponents : 4 , type : image instanceof HTMLImageElement ? "HTMLImageElement" : "HTMLCanvasElement" , data : image , dimensions : 2 } ; } getTextureData ( ) { return this . _data ; } } export function array ( ) { return new Array ( ) ; }