UNPKG

three

Version:

JavaScript 3D library

220 lines (150 loc) 4.02 kB
import { ImageUtils } from '../extras/ImageUtils.js'; import { generateUUID } from '../math/MathUtils.js'; let _sourceId = 0; /** * Represents the data source of a texture. * * The main purpose of this class is to decouple the data definition from the texture * definition so the same data can be used with multiple texture instances. */ class Source { /** * Constructs a new video texture. * * @param {any} [data=null] - The data definition of a texture. */ constructor( data = null ) { /** * This flag can be used for type testing. * * @type {boolean} * @readonly * @default true */ this.isSource = true; /** * The ID of the source. * * @name Source#id * @type {number} * @readonly */ Object.defineProperty( this, 'id', { value: _sourceId ++ } ); /** * The UUID of the source. * * @type {string} * @readonly */ this.uuid = generateUUID(); /** * The data definition of a texture. * * @type {any} */ this.data = data; /** * This property is only relevant when {@link Source#needsUpdate} is set to `true` and * provides more control on how texture data should be processed. When `dataReady` is set * to `false`, the engine performs the memory allocation (if necessary) but does not transfer * the data into the GPU memory. * * @type {boolean} * @default true */ this.dataReady = true; /** * This starts at `0` and counts how many times {@link Source#needsUpdate} is set to `true`. * * @type {number} * @readonly * @default 0 */ this.version = 0; } getSize( target ) { const data = this.data; if ( data instanceof HTMLVideoElement ) { target.set( data.videoWidth, data.videoHeight ); } else if ( data !== null ) { target.set( data.width, data.height, data.depth || 0 ); } else { target.set( 0, 0, 0 ); } return target; } /** * When the property is set to `true`, the engine allocates the memory * for the texture (if necessary) and triggers the actual texture upload * to the GPU next time the source is used. * * @type {boolean} * @default false * @param {boolean} value */ set needsUpdate( value ) { if ( value === true ) this.version ++; } /** * Serializes the source into JSON. * * @param {?(Object|string)} meta - An optional value holding meta information about the serialization. * @return {Object} A JSON object representing the serialized source. * @see {@link ObjectLoader#parse} */ toJSON( meta ) { const isRootObject = ( meta === undefined || typeof meta === 'string' ); if ( ! isRootObject && meta.images[ this.uuid ] !== undefined ) { return meta.images[ this.uuid ]; } const output = { uuid: this.uuid, url: '' }; const data = this.data; if ( data !== null ) { let url; if ( Array.isArray( data ) ) { // cube texture url = []; for ( let i = 0, l = data.length; i < l; i ++ ) { if ( data[ i ].isDataTexture ) { url.push( serializeImage( data[ i ].image ) ); } else { url.push( serializeImage( data[ i ] ) ); } } } else { // texture url = serializeImage( data ); } output.url = url; } if ( ! isRootObject ) { meta.images[ this.uuid ] = output; } return output; } } function serializeImage( image ) { if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) || ( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) || ( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) { // default images return ImageUtils.getDataURL( image ); } else { if ( image.data ) { // images of DataTexture return { data: Array.from( image.data ), width: image.width, height: image.height, type: image.data.constructor.name }; } else { console.warn( 'THREE.Texture: Unable to serialize Texture.' ); return {}; } } } export { Source };