Buckets:
| import { Color } from '../../math/Color.js'; | |
| import { Matrix2 } from '../../math/Matrix2.js'; | |
| import { Matrix3 } from '../../math/Matrix3.js'; | |
| import { Matrix4 } from '../../math/Matrix4.js'; | |
| import { Vector2 } from '../../math/Vector2.js'; | |
| import { Vector3 } from '../../math/Vector3.js'; | |
| import { Vector4 } from '../../math/Vector4.js'; | |
| // cyrb53 (c) 2018 bryc (github.com/bryc). License: Public domain. Attribution appreciated. | |
| // A fast and simple 64-bit (or 53-bit) string hash function with decent collision resistance. | |
| // Largely inspired by MurmurHash2/3, but with a focus on speed/simplicity. | |
| // See https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript/52171480#52171480 | |
| // https://github.com/bryc/code/blob/master/jshash/experimental/cyrb53.js | |
| function cyrb53( value, seed = 0 ) { | |
| let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed; | |
| if ( value instanceof Array ) { | |
| for ( let i = 0, val; i < value.length; i ++ ) { | |
| val = value[ i ]; | |
| h1 = Math.imul( h1 ^ val, 2654435761 ); | |
| h2 = Math.imul( h2 ^ val, 1597334677 ); | |
| } | |
| } else { | |
| for ( let i = 0, ch; i < value.length; i ++ ) { | |
| ch = value.charCodeAt( i ); | |
| h1 = Math.imul( h1 ^ ch, 2654435761 ); | |
| h2 = Math.imul( h2 ^ ch, 1597334677 ); | |
| } | |
| } | |
| h1 = Math.imul( h1 ^ ( h1 >>> 16 ), 2246822507 ); | |
| h1 ^= Math.imul( h2 ^ ( h2 >>> 13 ), 3266489909 ); | |
| h2 = Math.imul( h2 ^ ( h2 >>> 16 ), 2246822507 ); | |
| h2 ^= Math.imul( h1 ^ ( h1 >>> 13 ), 3266489909 ); | |
| return 4294967296 * ( 2097151 & h2 ) + ( h1 >>> 0 ); | |
| } | |
| /** | |
| * Computes a hash for the given string. | |
| * | |
| * @method | |
| * @param {string} str - The string to be hashed. | |
| * @return {number} The hash. | |
| */ | |
| export const hashString = ( str ) => cyrb53( str ); | |
| /** | |
| * Computes a hash for the given array. | |
| * | |
| * @method | |
| * @param {Array<number>} array - The array to be hashed. | |
| * @return {number} The hash. | |
| */ | |
| export const hashArray = ( array ) => cyrb53( array ); | |
| /** | |
| * Computes a hash for the given list of parameters. | |
| * | |
| * @method | |
| * @param {...number} params - A list of parameters. | |
| * @return {number} The hash. | |
| */ | |
| export const hash = ( ...params ) => cyrb53( params ); | |
| /** | |
| * Computes a cache key for the given node. | |
| * | |
| * @method | |
| * @param {Object|Node} object - The object to be hashed. | |
| * @param {boolean} [force=false] - Whether to force a cache key computation or not. | |
| * @return {number} The hash. | |
| */ | |
| export function getCacheKey( object, force = false ) { | |
| const values = []; | |
| if ( object.isNode === true ) { | |
| values.push( object.id ); | |
| object = object.getSelf(); | |
| } | |
| for ( const { property, childNode } of getNodeChildren( object ) ) { | |
| values.push( cyrb53( property.slice( 0, - 4 ) ), childNode.getCacheKey( force ) ); | |
| } | |
| return cyrb53( values ); | |
| } | |
| /** | |
| * This generator function can be used to iterate over the node children | |
| * of the given object. | |
| * | |
| * @generator | |
| * @param {Object} node - The object to be hashed. | |
| * @param {boolean} [toJSON=false] - Whether to return JSON or not. | |
| * @yields {Object} A result node holding the property, index (if available) and the child node. | |
| */ | |
| export function* getNodeChildren( node, toJSON = false ) { | |
| for ( const property in node ) { | |
| // Ignore private properties. | |
| if ( property.startsWith( '_' ) === true ) continue; | |
| const object = node[ property ]; | |
| if ( Array.isArray( object ) === true ) { | |
| for ( let i = 0; i < object.length; i ++ ) { | |
| const child = object[ i ]; | |
| if ( child && ( child.isNode === true || toJSON && typeof child.toJSON === 'function' ) ) { | |
| yield { property, index: i, childNode: child }; | |
| } | |
| } | |
| } else if ( object && object.isNode === true ) { | |
| yield { property, childNode: object }; | |
| } else if ( typeof object === 'object' ) { | |
| for ( const subProperty in object ) { | |
| const child = object[ subProperty ]; | |
| if ( child && ( child.isNode === true || toJSON && typeof child.toJSON === 'function' ) ) { | |
| yield { property, index: subProperty, childNode: child }; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| const typeFromLength = /*@__PURE__*/ new Map( [ | |
| [ 1, 'float' ], | |
| [ 2, 'vec2' ], | |
| [ 3, 'vec3' ], | |
| [ 4, 'vec4' ], | |
| [ 9, 'mat3' ], | |
| [ 16, 'mat4' ] | |
| ] ); | |
| const dataFromObject = /*@__PURE__*/ new WeakMap(); | |
| /** | |
| * Returns the data type for the given the length. | |
| * | |
| * @method | |
| * @param {number} length - The length. | |
| * @return {string} The data type. | |
| */ | |
| export function getTypeFromLength( length ) { | |
| return typeFromLength.get( length ); | |
| } | |
| /** | |
| * Returns the typed array for the given data type. | |
| * | |
| * @method | |
| * @param {string} type - The data type. | |
| * @return {TypedArray} The typed array. | |
| */ | |
| export function getTypedArrayFromType( type ) { | |
| // Handle component type for vectors and matrices | |
| if ( /[iu]?vec\d/.test( type ) ) { | |
| // Handle int vectors | |
| if ( type.startsWith( 'ivec' ) ) return Int32Array; | |
| // Handle uint vectors | |
| if ( type.startsWith( 'uvec' ) ) return Uint32Array; | |
| // Default to float vectors | |
| return Float32Array; | |
| } | |
| // Handle matrices (always float) | |
| if ( /mat\d/.test( type ) ) return Float32Array; | |
| // Basic types | |
| if ( /float/.test( type ) ) return Float32Array; | |
| if ( /uint/.test( type ) ) return Uint32Array; | |
| if ( /int/.test( type ) ) return Int32Array; | |
| throw new Error( `THREE.NodeUtils: Unsupported type: ${type}` ); | |
| } | |
| /** | |
| * Returns the length for the given data type. | |
| * | |
| * @method | |
| * @param {string} type - The data type. | |
| * @return {number} The length. | |
| */ | |
| export function getLengthFromType( type ) { | |
| if ( /float|int|uint/.test( type ) ) return 1; | |
| if ( /vec2/.test( type ) ) return 2; | |
| if ( /vec3/.test( type ) ) return 3; | |
| if ( /vec4/.test( type ) ) return 4; | |
| if ( /mat2/.test( type ) ) return 4; | |
| if ( /mat3/.test( type ) ) return 9; | |
| if ( /mat4/.test( type ) ) return 16; | |
| console.error( 'THREE.TSL: Unsupported type:', type ); | |
| } | |
| /** | |
| * Returns the data type for the given value. | |
| * | |
| * @method | |
| * @param {any} value - The value. | |
| * @return {?string} The data type. | |
| */ | |
| export function getValueType( value ) { | |
| if ( value === undefined || value === null ) return null; | |
| const typeOf = typeof value; | |
| if ( value.isNode === true ) { | |
| return 'node'; | |
| } else if ( typeOf === 'number' ) { | |
| return 'float'; | |
| } else if ( typeOf === 'boolean' ) { | |
| return 'bool'; | |
| } else if ( typeOf === 'string' ) { | |
| return 'string'; | |
| } else if ( typeOf === 'function' ) { | |
| return 'shader'; | |
| } else if ( value.isVector2 === true ) { | |
| return 'vec2'; | |
| } else if ( value.isVector3 === true ) { | |
| return 'vec3'; | |
| } else if ( value.isVector4 === true ) { | |
| return 'vec4'; | |
| } else if ( value.isMatrix2 === true ) { | |
| return 'mat2'; | |
| } else if ( value.isMatrix3 === true ) { | |
| return 'mat3'; | |
| } else if ( value.isMatrix4 === true ) { | |
| return 'mat4'; | |
| } else if ( value.isColor === true ) { | |
| return 'color'; | |
| } else if ( value instanceof ArrayBuffer ) { | |
| return 'ArrayBuffer'; | |
| } | |
| return null; | |
| } | |
| /** | |
| * Returns the value/object for the given data type and parameters. | |
| * | |
| * @method | |
| * @param {string} type - The given type. | |
| * @param {...any} params - A parameter list. | |
| * @return {any} The value/object. | |
| */ | |
| export function getValueFromType( type, ...params ) { | |
| const last4 = type ? type.slice( - 4 ) : undefined; | |
| if ( params.length === 1 ) { // ensure same behaviour as in NodeBuilder.format() | |
| if ( last4 === 'vec2' ) params = [ params[ 0 ], params[ 0 ] ]; | |
| else if ( last4 === 'vec3' ) params = [ params[ 0 ], params[ 0 ], params[ 0 ] ]; | |
| else if ( last4 === 'vec4' ) params = [ params[ 0 ], params[ 0 ], params[ 0 ], params[ 0 ] ]; | |
| } | |
| if ( type === 'color' ) { | |
| return new Color( ...params ); | |
| } else if ( last4 === 'vec2' ) { | |
| return new Vector2( ...params ); | |
| } else if ( last4 === 'vec3' ) { | |
| return new Vector3( ...params ); | |
| } else if ( last4 === 'vec4' ) { | |
| return new Vector4( ...params ); | |
| } else if ( last4 === 'mat2' ) { | |
| return new Matrix2( ...params ); | |
| } else if ( last4 === 'mat3' ) { | |
| return new Matrix3( ...params ); | |
| } else if ( last4 === 'mat4' ) { | |
| return new Matrix4( ...params ); | |
| } else if ( type === 'bool' ) { | |
| return params[ 0 ] || false; | |
| } else if ( ( type === 'float' ) || ( type === 'int' ) || ( type === 'uint' ) ) { | |
| return params[ 0 ] || 0; | |
| } else if ( type === 'string' ) { | |
| return params[ 0 ] || ''; | |
| } else if ( type === 'ArrayBuffer' ) { | |
| return base64ToArrayBuffer( params[ 0 ] ); | |
| } | |
| return null; | |
| } | |
| /** | |
| * Gets the object data that can be shared between different rendering steps. | |
| * | |
| * @param {Object} object - The object to get the data for. | |
| * @return {Object} The object data. | |
| */ | |
| export function getDataFromObject( object ) { | |
| let data = dataFromObject.get( object ); | |
| if ( data === undefined ) { | |
| data = {}; | |
| dataFromObject.set( object, data ); | |
| } | |
| return data; | |
| } | |
| /** | |
| * Converts the given array buffer to a Base64 string. | |
| * | |
| * @method | |
| * @param {ArrayBuffer} arrayBuffer - The array buffer. | |
| * @return {string} The Base64 string. | |
| */ | |
| export function arrayBufferToBase64( arrayBuffer ) { | |
| let chars = ''; | |
| const array = new Uint8Array( arrayBuffer ); | |
| for ( let i = 0; i < array.length; i ++ ) { | |
| chars += String.fromCharCode( array[ i ] ); | |
| } | |
| return btoa( chars ); | |
| } | |
| /** | |
| * Converts the given Base64 string to an array buffer. | |
| * | |
| * @method | |
| * @param {string} base64 - The Base64 string. | |
| * @return {ArrayBuffer} The array buffer. | |
| */ | |
| export function base64ToArrayBuffer( base64 ) { | |
| return Uint8Array.from( atob( base64 ), c => c.charCodeAt( 0 ) ).buffer; | |
| } | |
Xet Storage Details
- Size:
- 9.46 kB
- Xet hash:
- 5935e1a5468b3028e9ae1b2adda8d20eabd22995892e06f413bade49f45196be
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.