function flatten( array, nBlocks, blockSize ) {

        var firstElem = array[ 0 ];

        if ( firstElem <= 0 || firstElem > 0 ) return array;
        // unoptimized: ! isNaN( firstElem )
        // see http://jacksondunstan.com/articles/983

        var n = nBlocks * blockSize,
            r = arrayCacheF32[ n ];

        if ( r === undefined ) {

            r = new Float32Array( n );
            arrayCacheF32[ n ] = r;

        }

        if ( nBlocks !== 0 ) {

            firstElem.toArray( r, 0 );

            for ( var i = 1, offset = 0; i !== nBlocks; ++ i ) {

                offset += blockSize;
                array[ i ].toArray( r, offset );

            }

        }

        return r;

    }
@author tschw
@author Mugen87 / https://github.com/Mugen87
@author mrdoob / http://mrdoob.com/

Uniforms of a program.
Those form a tree structure with a special top-level container for the root,
which you get by calling 'new WebGLUniforms( gl, program, renderer )'.


Properties of inner nodes including the top-level container:

.seq - array of nested uniforms
.map - nested uniforms by name


Methods of all nodes except the top-level container:

.setValue( gl, value, [renderer] )

        uploads a uniform value(s)
     the 'renderer' parameter is needed for sampler uniforms


Static methods of the top-level container (renderer factorizations):

.upload( gl, seq, values, renderer )

        sets uniforms in 'seq' to 'values[id].value'

.seqWithValue( seq, values ) : filteredSeq

        filters 'seq' entries with corresponding entry in values


Methods of the top-level container (renderer factorizations):

.setValue( gl, name, value )

        sets uniform with  name 'name' to 'value'

.set( gl, obj, prop )

        sets uniform from object and property with same name than uniform

.setOptional( gl, obj, prop )

        like .set for an optional property of the object