Skip to content

⬅️ Back to Table of Contents

📄 ObjectLoader.js

📊 Analysis Summary

Metric Count
🔧 Functions 22
🧱 Classes 1
📦 Imports 59
📊 Variables & Constants 71
⚡ Async/Await Patterns 1

📚 Table of Contents

🛠️ File Location:

📂 src/loaders/ObjectLoader.js

📦 Imports

Name Source
UVMapping ../constants.js
CubeReflectionMapping ../constants.js
CubeRefractionMapping ../constants.js
EquirectangularReflectionMapping ../constants.js
EquirectangularRefractionMapping ../constants.js
CubeUVReflectionMapping ../constants.js
RepeatWrapping ../constants.js
ClampToEdgeWrapping ../constants.js
MirroredRepeatWrapping ../constants.js
NearestFilter ../constants.js
NearestMipmapNearestFilter ../constants.js
NearestMipmapLinearFilter ../constants.js
LinearFilter ../constants.js
LinearMipmapNearestFilter ../constants.js
LinearMipmapLinearFilter ../constants.js
InstancedBufferAttribute ../core/InstancedBufferAttribute.js
Color ../math/Color.js
Object3D ../core/Object3D.js
Group ../objects/Group.js
InstancedMesh ../objects/InstancedMesh.js
BatchedMesh ../objects/BatchedMesh.js
Sprite ../objects/Sprite.js
Points ../objects/Points.js
Line ../objects/Line.js
LineLoop ../objects/LineLoop.js
LineSegments ../objects/LineSegments.js
LOD ../objects/LOD.js
Mesh ../objects/Mesh.js
SkinnedMesh ../objects/SkinnedMesh.js
Bone ../objects/Bone.js
Skeleton ../objects/Skeleton.js
Shape ../extras/core/Shape.js
Fog ../scenes/Fog.js
FogExp2 ../scenes/FogExp2.js
HemisphereLight ../lights/HemisphereLight.js
SpotLight ../lights/SpotLight.js
PointLight ../lights/PointLight.js
DirectionalLight ../lights/DirectionalLight.js
AmbientLight ../lights/AmbientLight.js
RectAreaLight ../lights/RectAreaLight.js
LightProbe ../lights/LightProbe.js
OrthographicCamera ../cameras/OrthographicCamera.js
PerspectiveCamera ../cameras/PerspectiveCamera.js
Scene ../scenes/Scene.js
CubeTexture ../textures/CubeTexture.js
Texture ../textures/Texture.js
Source ../textures/Source.js
DataTexture ../textures/DataTexture.js
ImageLoader ./ImageLoader.js
LoadingManager ./LoadingManager.js
AnimationClip ../animation/AnimationClip.js
MaterialLoader ./MaterialLoader.js
LoaderUtils ./LoaderUtils.js
BufferGeometryLoader ./BufferGeometryLoader.js
Loader ./Loader.js
FileLoader ./FileLoader.js
getTypedArray ../utils.js
Box3 ../math/Box3.js
Sphere ../math/Sphere.js

Variables & Constants

Name Type Kind Value Exported
scope this let/var this
path string let/var ( this.path === '' ) ? LoaderUtils.extractUrlBase( url ) : this.path
loader FileLoader let/var new FileLoader( this.manager )
json any let/var null
metadata any let/var json.metadata
scope this let/var this
path string let/var ( this.path === '' ) ? LoaderUtils.extractUrlBase( url ) : this.path
loader FileLoader let/var new FileLoader( this.manager )
text any let/var await loader.loadAsync( url, onProgress )
metadata any let/var json.metadata
hasImages boolean let/var false
images {} let/var await this.parseImagesAsync( json.images )
shapes {} let/var {}
skeletons {} let/var {}
bones {} let/var {}
geometries {} let/var {}
bufferGeometryLoader BufferGeometryLoader let/var new BufferGeometryLoader()
geometry any let/var *not shown*
data any let/var json[ i ]
cache {} let/var {}
materials {} let/var {}
loader MaterialLoader let/var new MaterialLoader()
data any let/var json[ i ]
animations {} let/var {}
data any let/var json[ i ]
scope this let/var this
images {} let/var {}
loader any let/var *not shown*
url string let/var image
path string let/var /^(\/\/)\|([a-z]+:(\/\/)?)/i.test( url ) ? url : scope.resourcePath + url
manager LoadingManager let/var new LoadingManager( onLoad )
image any let/var json[ i ]
url any let/var image.url
imageArray any[] let/var []
currentUrl any let/var url[ j ]
scope this let/var this
images {} let/var {}
loader any let/var *not shown*
url string let/var image
path string let/var /^(\/\/)\|([a-z]+:(\/\/)?)/i.test( url ) ? url : scope.resourcePath + url
image any let/var json[ i ]
url any let/var image.url
imageArray any[] let/var []
currentUrl any let/var url[ j ]
deserializedImage any let/var await deserializeImage( currentUrl )
deserializedImage any let/var await deserializeImage( image.url )
textures {} let/var {}
data any let/var json[ i ]
source any let/var images[ data.image ]
image any let/var source.data
texture any let/var *not shown*
object any let/var *not shown*
array any[] let/var []
uuid any let/var name[ i ]
geometry any let/var *not shown*
material any let/var *not shown*
count any let/var data.count
instanceMatrix any let/var data.instanceMatrix
instanceColor any let/var data.instanceColor
box any let/var null
sphere any let/var null
children any let/var data.children
objectAnimations any let/var data.animations
uuid any let/var objectAnimations[ i ]
levels any let/var data.levels
level any let/var levels[ l ]
skeleton any let/var skeletons[ child.skeleton ]
uuid any let/var child.target
TEXTURE_MAPPING { UVMapping: number; CubeReflectionMa... let/var { UVMapping: UVMapping, CubeReflectionMapping: CubeReflectionMapping, CubeRef...
TEXTURE_WRAPPING { RepeatWrapping: number; ClampToEdge... let/var { RepeatWrapping: RepeatWrapping, ClampToEdgeWrapping: ClampToEdgeWrapping, M...
TEXTURE_FILTER { NearestFilter: number; NearestMipma... let/var { NearestFilter: NearestFilter, NearestMipmapNearestFilter: NearestMipmapNear...

Async/Await Patterns

Type Function Await Expressions Promise Chains
async-function deserializeImage loader.loadAsync( path ) none

Functions

ObjectLoader.load(url: string, onLoad: (arg0: Object3D) => any, onProgress: onProgressCallback, onError: onErrorCallback): void

JSDoc:

/**
     * Starts loading from the given URL and pass the loaded 3D object to the `onLoad()` callback.
     *
     * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.
     * @param {function(Object3D)} onLoad - Executed when the loading process has been finished.
     * @param {onProgressCallback} onProgress - Executed while the loading is in progress.
     * @param {onErrorCallback} onError - Executed when errors occur.
     */

Parameters:

  • url string
  • onLoad (arg0: Object3D) => any
  • onProgress onProgressCallback
  • onError onErrorCallback

Returns: void

Calls:

  • LoaderUtils.extractUrlBase
  • loader.setPath
  • loader.setRequestHeader
  • loader.setWithCredentials
  • loader.load
  • JSON.parse
  • onError
  • console.error
  • metadata.type.toLowerCase
  • scope.parse
Code
load( url, onLoad, onProgress, onError ) {

        const scope = this;

        const path = ( this.path === '' ) ? LoaderUtils.extractUrlBase( url ) : this.path;
        this.resourcePath = this.resourcePath || path;

        const loader = new FileLoader( this.manager );
        loader.setPath( this.path );
        loader.setRequestHeader( this.requestHeader );
        loader.setWithCredentials( this.withCredentials );
        loader.load( url, function ( text ) {

            let json = null;

            try {

                json = JSON.parse( text );

            } catch ( error ) {

                if ( onError !== undefined ) onError( error );

                console.error( 'THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message );

                return;

            }

            const metadata = json.metadata;

            if ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {

                if ( onError !== undefined ) onError( new Error( 'THREE.ObjectLoader: Can\'t load ' + url ) );

                console.error( 'THREE.ObjectLoader: Can\'t load ' + url );
                return;

            }

            scope.parse( json, onLoad );

        }, onProgress, onError );

    }

ObjectLoader.loadAsync(url: string, onProgress: onProgressCallback): Promise<Object3D>

JSDoc:

/**
     * Async version of {@link ObjectLoader#load}.
     *
     * @async
     * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.
     * @param {onProgressCallback} onProgress - Executed while the loading is in progress.
     * @return {Promise<Object3D>} A Promise that resolves with the loaded 3D object.
     */

Parameters:

  • url string
  • onProgress onProgressCallback

Returns: Promise<Object3D>

Calls:

  • LoaderUtils.extractUrlBase
  • loader.setPath
  • loader.setRequestHeader
  • loader.setWithCredentials
  • loader.loadAsync
  • JSON.parse
  • metadata.type.toLowerCase
  • scope.parseAsync
Code
async loadAsync( url, onProgress ) {

        const scope = this;

        const path = ( this.path === '' ) ? LoaderUtils.extractUrlBase( url ) : this.path;
        this.resourcePath = this.resourcePath || path;

        const loader = new FileLoader( this.manager );
        loader.setPath( this.path );
        loader.setRequestHeader( this.requestHeader );
        loader.setWithCredentials( this.withCredentials );

        const text = await loader.loadAsync( url, onProgress );

        const json = JSON.parse( text );

        const metadata = json.metadata;

        if ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {

            throw new Error( 'THREE.ObjectLoader: Can\'t load ' + url );

        }

        return await scope.parseAsync( json );

    }

ObjectLoader.parse(json: any, onLoad: any): Object3D

JSDoc:

/**
     * Parses the given JSON. This is used internally by {@link ObjectLoader#load}
     * but can also be used directly to parse a previously loaded JSON structure.
     *
     * @param {Object} json - The serialized 3D object.
     * @param {onLoad} onLoad - Executed when all resources (e.g. textures) have been fully loaded.
     * @return {Object3D} The parsed 3D object.
     */

Parameters:

  • json any
  • onLoad any

Returns: Object3D

Calls:

  • this.parseAnimations
  • this.parseShapes
  • this.parseGeometries
  • this.parseImages
  • onLoad
  • this.parseTextures
  • this.parseMaterials
  • this.parseObject
  • this.parseSkeletons
  • this.bindSkeletons
  • this.bindLightTargets

Internal Comments:

//

Code
parse( json, onLoad ) {

        const animations = this.parseAnimations( json.animations );
        const shapes = this.parseShapes( json.shapes );
        const geometries = this.parseGeometries( json.geometries, shapes );

        const images = this.parseImages( json.images, function () {

            if ( onLoad !== undefined ) onLoad( object );

        } );

        const textures = this.parseTextures( json.textures, images );
        const materials = this.parseMaterials( json.materials, textures );

        const object = this.parseObject( json.object, geometries, materials, textures, animations );
        const skeletons = this.parseSkeletons( json.skeletons, object );

        this.bindSkeletons( object, skeletons );
        this.bindLightTargets( object );

        //

        if ( onLoad !== undefined ) {

            let hasImages = false;

            for ( const uuid in images ) {

                if ( images[ uuid ].data instanceof HTMLImageElement ) {

                    hasImages = true;
                    break;

                }

            }

            if ( hasImages === false ) onLoad( object );

        }

        return object;

    }

ObjectLoader.parseAsync(json: any): Promise<Object3D>

JSDoc:

/**
     * Async version of {@link ObjectLoader#parse}.
     *
     * @param {Object} json - The serialized 3D object.
     * @return {Promise<Object3D>} A Promise that resolves with the parsed 3D object.
     */

Parameters:

  • json any

Returns: Promise<Object3D>

Calls:

  • this.parseAnimations
  • this.parseShapes
  • this.parseGeometries
  • this.parseImagesAsync
  • this.parseTextures
  • this.parseMaterials
  • this.parseObject
  • this.parseSkeletons
  • this.bindSkeletons
  • this.bindLightTargets
Code
async parseAsync( json ) {

        const animations = this.parseAnimations( json.animations );
        const shapes = this.parseShapes( json.shapes );
        const geometries = this.parseGeometries( json.geometries, shapes );

        const images = await this.parseImagesAsync( json.images );

        const textures = this.parseTextures( json.textures, images );
        const materials = this.parseMaterials( json.materials, textures );

        const object = this.parseObject( json.object, geometries, materials, textures, animations );
        const skeletons = this.parseSkeletons( json.skeletons, object );

        this.bindSkeletons( object, skeletons );
        this.bindLightTargets( object );

        return object;

    }

ObjectLoader.parseShapes(json: any): {}

Parameters:

  • json any

Returns: {}

Calls:

  • new Shape().fromJSON
Code
parseShapes( json ) {

        const shapes = {};

        if ( json !== undefined ) {

            for ( let i = 0, l = json.length; i < l; i ++ ) {

                const shape = new Shape().fromJSON( json[ i ] );

                shapes[ shape.uuid ] = shape;

            }

        }

        return shapes;

    }

ObjectLoader.parseSkeletons(json: any, object: any): {}

Parameters:

  • json any
  • object any

Returns: {}

Calls:

  • object.traverse
  • new Skeleton().fromJSON

Internal Comments:

// generate bone lookup table (x4)
// create skeletons

Code
parseSkeletons( json, object ) {

        const skeletons = {};
        const bones = {};

        // generate bone lookup table

        object.traverse( function ( child ) {

            if ( child.isBone ) bones[ child.uuid ] = child;

        } );

        // create skeletons

        if ( json !== undefined ) {

            for ( let i = 0, l = json.length; i < l; i ++ ) {

                const skeleton = new Skeleton().fromJSON( json[ i ], bones );

                skeletons[ skeleton.uuid ] = skeleton;

            }

        }

        return skeletons;

    }

ObjectLoader.parseGeometries(json: any, shapes: any): {}

Parameters:

  • json any
  • shapes any

Returns: {}

Calls:

  • bufferGeometryLoader.parse
  • Geometries[ data.type ].fromJSON
  • console.warn
Code
parseGeometries( json, shapes ) {

        const geometries = {};

        if ( json !== undefined ) {

            const bufferGeometryLoader = new BufferGeometryLoader();

            for ( let i = 0, l = json.length; i < l; i ++ ) {

                let geometry;
                const data = json[ i ];

                switch ( data.type ) {

                    case 'BufferGeometry':
                    case 'InstancedBufferGeometry':

                        geometry = bufferGeometryLoader.parse( data );
                        break;

                    default:

                        if ( data.type in Geometries ) {

                            geometry = Geometries[ data.type ].fromJSON( data, shapes );

                        } else {

                            console.warn( `THREE.ObjectLoader: Unsupported geometry type "${ data.type }"` );

                        }

                }

                geometry.uuid = data.uuid;

                if ( data.name !== undefined ) geometry.name = data.name;
                if ( data.userData !== undefined ) geometry.userData = data.userData;

                geometries[ data.uuid ] = geometry;

            }

        }

        return geometries;

    }

ObjectLoader.parseMaterials(json: any, textures: any): {}

Parameters:

  • json any
  • textures any

Returns: {}

Calls:

  • loader.setTextures
  • loader.parse
Code
parseMaterials( json, textures ) {

        const cache = {}; // MultiMaterial
        const materials = {};

        if ( json !== undefined ) {

            const loader = new MaterialLoader();
            loader.setTextures( textures );

            for ( let i = 0, l = json.length; i < l; i ++ ) {

                const data = json[ i ];

                if ( cache[ data.uuid ] === undefined ) {

                    cache[ data.uuid ] = loader.parse( data );

                }

                materials[ data.uuid ] = cache[ data.uuid ];

            }

        }

        return materials;

    }

ObjectLoader.parseAnimations(json: any): {}

Parameters:

  • json any

Returns: {}

Calls:

  • AnimationClip.parse
Code
parseAnimations( json ) {

        const animations = {};

        if ( json !== undefined ) {

            for ( let i = 0; i < json.length; i ++ ) {

                const data = json[ i ];

                const clip = AnimationClip.parse( data );

                animations[ clip.uuid ] = clip;

            }

        }

        return animations;

    }

ObjectLoader.parseImages(json: any, onLoad: any): {}

Parameters:

  • json any
  • onLoad any

Returns: {}

Calls:

  • scope.manager.itemStart
  • loader.load
  • scope.manager.itemEnd
  • scope.manager.itemError
  • /^(\/\/)|([a-z]+:(\/\/)?)/i.test
  • loadImage
  • getTypedArray (from ../utils.js)
  • loader.setCrossOrigin
  • Array.isArray
  • deserializeImage
  • imageArray.push

Internal Comments:

// load array of images e.g CubeTexture (x2)
// special case: handle array of data textures for cube textures (x4)
// load single image (x2)

Code
parseImages( json, onLoad ) {

        const scope = this;
        const images = {};

        let loader;

        function loadImage( url ) {

            scope.manager.itemStart( url );

            return loader.load( url, function () {

                scope.manager.itemEnd( url );

            }, undefined, function () {

                scope.manager.itemError( url );
                scope.manager.itemEnd( url );

            } );

        }

        function deserializeImage( image ) {

            if ( typeof image === 'string' ) {

                const url = image;

                const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( url ) ? url : scope.resourcePath + url;

                return loadImage( path );

            } else {

                if ( image.data ) {

                    return {
                        data: getTypedArray( image.type, image.data ),
                        width: image.width,
                        height: image.height
                    };

                } else {

                    return null;

                }

            }

        }

        if ( json !== undefined && json.length > 0 ) {

            const manager = new LoadingManager( onLoad );

            loader = new ImageLoader( manager );
            loader.setCrossOrigin( this.crossOrigin );

            for ( let i = 0, il = json.length; i < il; i ++ ) {

                const image = json[ i ];
                const url = image.url;

                if ( Array.isArray( url ) ) {

                    // load array of images e.g CubeTexture

                    const imageArray = [];

                    for ( let j = 0, jl = url.length; j < jl; j ++ ) {

                        const currentUrl = url[ j ];

                        const deserializedImage = deserializeImage( currentUrl );

                        if ( deserializedImage !== null ) {

                            if ( deserializedImage instanceof HTMLImageElement ) {

                                imageArray.push( deserializedImage );

                            } else {

                                // special case: handle array of data textures for cube textures

                                imageArray.push( new DataTexture( deserializedImage.data, deserializedImage.width, deserializedImage.height ) );

                            }

                        }

                    }

                    images[ image.uuid ] = new Source( imageArray );

                } else {

                    // load single image

                    const deserializedImage = deserializeImage( image.url );
                    images[ image.uuid ] = new Source( deserializedImage );


                }

            }

        }

        return images;

    }

ObjectLoader.parseImagesAsync(json: any): Promise<{}>

Parameters:

  • json any

Returns: Promise<{}>

Calls:

  • /^(\/\/)|([a-z]+:(\/\/)?)/i.test
  • loader.loadAsync
  • getTypedArray (from ../utils.js)
  • loader.setCrossOrigin
  • Array.isArray
  • deserializeImage
  • imageArray.push

Internal Comments:

// load array of images e.g CubeTexture (x2)
// special case: handle array of data textures for cube textures (x4)
// load single image (x2)

Code
async parseImagesAsync( json ) {

        const scope = this;
        const images = {};

        let loader;

        async function deserializeImage( image ) {

            if ( typeof image === 'string' ) {

                const url = image;

                const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( url ) ? url : scope.resourcePath + url;

                return await loader.loadAsync( path );

            } else {

                if ( image.data ) {

                    return {
                        data: getTypedArray( image.type, image.data ),
                        width: image.width,
                        height: image.height
                    };

                } else {

                    return null;

                }

            }

        }

        if ( json !== undefined && json.length > 0 ) {

            loader = new ImageLoader( this.manager );
            loader.setCrossOrigin( this.crossOrigin );

            for ( let i = 0, il = json.length; i < il; i ++ ) {

                const image = json[ i ];
                const url = image.url;

                if ( Array.isArray( url ) ) {

                    // load array of images e.g CubeTexture

                    const imageArray = [];

                    for ( let j = 0, jl = url.length; j < jl; j ++ ) {

                        const currentUrl = url[ j ];

                        const deserializedImage = await deserializeImage( currentUrl );

                        if ( deserializedImage !== null ) {

                            if ( deserializedImage instanceof HTMLImageElement ) {

                                imageArray.push( deserializedImage );

                            } else {

                                // special case: handle array of data textures for cube textures

                                imageArray.push( new DataTexture( deserializedImage.data, deserializedImage.width, deserializedImage.height ) );

                            }

                        }

                    }

                    images[ image.uuid ] = new Source( imageArray );

                } else {

                    // load single image

                    const deserializedImage = await deserializeImage( image.url );
                    images[ image.uuid ] = new Source( deserializedImage );

                }

            }

        }

        return images;

    }

ObjectLoader.parseTextures(json: any, images: any): {}

Parameters:

  • json any
  • images any

Returns: {}

Calls:

  • console.warn
  • Array.isArray
  • parseConstant
  • texture.offset.fromArray
  • texture.repeat.fromArray
  • texture.center.fromArray
Code
parseTextures( json, images ) {

        function parseConstant( value, type ) {

            if ( typeof value === 'number' ) return value;

            console.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );

            return type[ value ];

        }

        const textures = {};

        if ( json !== undefined ) {

            for ( let i = 0, l = json.length; i < l; i ++ ) {

                const data = json[ i ];

                if ( data.image === undefined ) {

                    console.warn( 'THREE.ObjectLoader: No "image" specified for', data.uuid );

                }

                if ( images[ data.image ] === undefined ) {

                    console.warn( 'THREE.ObjectLoader: Undefined image', data.image );

                }

                const source = images[ data.image ];
                const image = source.data;

                let texture;

                if ( Array.isArray( image ) ) {

                    texture = new CubeTexture();

                    if ( image.length === 6 ) texture.needsUpdate = true;

                } else {

                    if ( image && image.data ) {

                        texture = new DataTexture();

                    } else {

                        texture = new Texture();

                    }

                    if ( image ) texture.needsUpdate = true; // textures can have undefined image data

                }

                texture.source = source;

                texture.uuid = data.uuid;

                if ( data.name !== undefined ) texture.name = data.name;

                if ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TEXTURE_MAPPING );
                if ( data.channel !== undefined ) texture.channel = data.channel;

                if ( data.offset !== undefined ) texture.offset.fromArray( data.offset );
                if ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat );
                if ( data.center !== undefined ) texture.center.fromArray( data.center );
                if ( data.rotation !== undefined ) texture.rotation = data.rotation;

                if ( data.wrap !== undefined ) {

                    texture.wrapS = parseConstant( data.wrap[ 0 ], TEXTURE_WRAPPING );
                    texture.wrapT = parseConstant( data.wrap[ 1 ], TEXTURE_WRAPPING );

                }

                if ( data.format !== undefined ) texture.format = data.format;
                if ( data.internalFormat !== undefined ) texture.internalFormat = data.internalFormat;
                if ( data.type !== undefined ) texture.type = data.type;
                if ( data.colorSpace !== undefined ) texture.colorSpace = data.colorSpace;

                if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TEXTURE_FILTER );
                if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TEXTURE_FILTER );
                if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;

                if ( data.flipY !== undefined ) texture.flipY = data.flipY;

                if ( data.generateMipmaps !== undefined ) texture.generateMipmaps = data.generateMipmaps;
                if ( data.premultiplyAlpha !== undefined ) texture.premultiplyAlpha = data.premultiplyAlpha;
                if ( data.unpackAlignment !== undefined ) texture.unpackAlignment = data.unpackAlignment;
                if ( data.compareFunction !== undefined ) texture.compareFunction = data.compareFunction;

                if ( data.userData !== undefined ) texture.userData = data.userData;

                textures[ data.uuid ] = texture;

            }

        }

        return textures;

    }

ObjectLoader.parseObject(data: any, geometries: any, materials: any, textures: any, animations: any): Object3D | Mesh | PerspectiveCamera | Scene | Sprite | LOD | SkinnedMesh | InstancedMesh | ... 10 more ... | AmbientLight

Parameters:

  • data any
  • geometries any
  • materials any
  • textures any
  • animations any

Returns: Object3D | Mesh | PerspectiveCamera | Scene | Sprite | LOD | SkinnedMesh | InstancedMesh | ... 10 more ... | AmbientLight

Calls:

  • console.warn
  • Array.isArray
  • array.push
  • Number.isInteger
  • getTexture
  • object.backgroundRotation.fromArray
  • object.environmentRotation.fromArray
  • Object.assign
  • new LightProbe().fromJSON
  • getGeometry
  • getMaterial
  • object.bindMatrix.fromArray
  • data.geometryInfo.map
  • new Box3().fromJSON
  • new Sphere().fromJSON
  • object.matrix.fromArray
  • object.matrix.decompose
  • object.position.fromArray
  • object.rotation.fromArray
  • object.quaternion.fromArray
  • object.scale.fromArray
  • object.up.fromArray
  • object.shadow.mapSize.fromArray
  • this.parseObject
  • object.add
  • object.animations.push
  • object.getObjectByProperty
  • object.addLevel
Code
parseObject( data, geometries, materials, textures, animations ) {

        let object;

        function getGeometry( name ) {

            if ( geometries[ name ] === undefined ) {

                console.warn( 'THREE.ObjectLoader: Undefined geometry', name );

            }

            return geometries[ name ];

        }

        function getMaterial( name ) {

            if ( name === undefined ) return undefined;

            if ( Array.isArray( name ) ) {

                const array = [];

                for ( let i = 0, l = name.length; i < l; i ++ ) {

                    const uuid = name[ i ];

                    if ( materials[ uuid ] === undefined ) {

                        console.warn( 'THREE.ObjectLoader: Undefined material', uuid );

                    }

                    array.push( materials[ uuid ] );

                }

                return array;

            }

            if ( materials[ name ] === undefined ) {

                console.warn( 'THREE.ObjectLoader: Undefined material', name );

            }

            return materials[ name ];

        }

        function getTexture( uuid ) {

            if ( textures[ uuid ] === undefined ) {

                console.warn( 'THREE.ObjectLoader: Undefined texture', uuid );

            }

            return textures[ uuid ];

        }

        let geometry, material;

        switch ( data.type ) {

            case 'Scene':

                object = new Scene();

                if ( data.background !== undefined ) {

                    if ( Number.isInteger( data.background ) ) {

                        object.background = new Color( data.background );

                    } else {

                        object.background = getTexture( data.background );

                    }

                }

                if ( data.environment !== undefined ) {

                    object.environment = getTexture( data.environment );

                }

                if ( data.fog !== undefined ) {

                    if ( data.fog.type === 'Fog' ) {

                        object.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );

                    } else if ( data.fog.type === 'FogExp2' ) {

                        object.fog = new FogExp2( data.fog.color, data.fog.density );

                    }

                    if ( data.fog.name !== '' ) {

                        object.fog.name = data.fog.name;

                    }

                }

                if ( data.backgroundBlurriness !== undefined ) object.backgroundBlurriness = data.backgroundBlurriness;
                if ( data.backgroundIntensity !== undefined ) object.backgroundIntensity = data.backgroundIntensity;
                if ( data.backgroundRotation !== undefined ) object.backgroundRotation.fromArray( data.backgroundRotation );

                if ( data.environmentIntensity !== undefined ) object.environmentIntensity = data.environmentIntensity;
                if ( data.environmentRotation !== undefined ) object.environmentRotation.fromArray( data.environmentRotation );

                break;

            case 'PerspectiveCamera':

                object = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );

                if ( data.focus !== undefined ) object.focus = data.focus;
                if ( data.zoom !== undefined ) object.zoom = data.zoom;
                if ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge;
                if ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset;
                if ( data.view !== undefined ) object.view = Object.assign( {}, data.view );

                break;

            case 'OrthographicCamera':

                object = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );

                if ( data.zoom !== undefined ) object.zoom = data.zoom;
                if ( data.view !== undefined ) object.view = Object.assign( {}, data.view );

                break;

            case 'AmbientLight':

                object = new AmbientLight( data.color, data.intensity );

                break;

            case 'DirectionalLight':

                object = new DirectionalLight( data.color, data.intensity );
                object.target = data.target || '';

                break;

            case 'PointLight':

                object = new PointLight( data.color, data.intensity, data.distance, data.decay );

                break;

            case 'RectAreaLight':

                object = new RectAreaLight( data.color, data.intensity, data.width, data.height );

                break;

            case 'SpotLight':

                object = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );
                object.target = data.target || '';

                break;

            case 'HemisphereLight':

                object = new HemisphereLight( data.color, data.groundColor, data.intensity );

                break;

            case 'LightProbe':

                object = new LightProbe().fromJSON( data );

                break;

            case 'SkinnedMesh':

                geometry = getGeometry( data.geometry );
                material = getMaterial( data.material );

                object = new SkinnedMesh( geometry, material );

                if ( data.bindMode !== undefined ) object.bindMode = data.bindMode;
                if ( data.bindMatrix !== undefined ) object.bindMatrix.fromArray( data.bindMatrix );
                if ( data.skeleton !== undefined ) object.skeleton = data.skeleton;

                break;

            case 'Mesh':

                geometry = getGeometry( data.geometry );
                material = getMaterial( data.material );

                object = new Mesh( geometry, material );

                break;

            case 'InstancedMesh':

                geometry = getGeometry( data.geometry );
                material = getMaterial( data.material );
                const count = data.count;
                const instanceMatrix = data.instanceMatrix;
                const instanceColor = data.instanceColor;

                object = new InstancedMesh( geometry, material, count );
                object.instanceMatrix = new InstancedBufferAttribute( new Float32Array( instanceMatrix.array ), 16 );
                if ( instanceColor !== undefined ) object.instanceColor = new InstancedBufferAttribute( new Float32Array( instanceColor.array ), instanceColor.itemSize );

                break;

            case 'BatchedMesh':

                geometry = getGeometry( data.geometry );
                material = getMaterial( data.material );

                object = new BatchedMesh( data.maxInstanceCount, data.maxVertexCount, data.maxIndexCount, material );
                object.geometry = geometry;
                object.perObjectFrustumCulled = data.perObjectFrustumCulled;
                object.sortObjects = data.sortObjects;

                object._drawRanges = data.drawRanges;
                object._reservedRanges = data.reservedRanges;

                object._geometryInfo = data.geometryInfo.map( info => {

                    let box = null;
                    let sphere = null;
                    if ( info.boundingBox !== undefined ) {

                        box = new Box3().fromJSON( info.boundingBox );

                    }

                    if ( info.boundingSphere !== undefined ) {

                        sphere = new Sphere().fromJSON( info.boundingSphere );

                    }

                    return {
                        ...info,
                        boundingBox: box,
                        boundingSphere: sphere
                    };

                } );
                object._instanceInfo = data.instanceInfo;

                object._availableInstanceIds = data._availableInstanceIds;
                object._availableGeometryIds = data._availableGeometryIds;

                object._nextIndexStart = data.nextIndexStart;
                object._nextVertexStart = data.nextVertexStart;
                object._geometryCount = data.geometryCount;

                object._maxInstanceCount = data.maxInstanceCount;
                object._maxVertexCount = data.maxVertexCount;
                object._maxIndexCount = data.maxIndexCount;

                object._geometryInitialized = data.geometryInitialized;

                object._matricesTexture = getTexture( data.matricesTexture.uuid );

                object._indirectTexture = getTexture( data.indirectTexture.uuid );

                if ( data.colorsTexture !== undefined ) {

                    object._colorsTexture = getTexture( data.colorsTexture.uuid );

                }

                if ( data.boundingSphere !== undefined ) {

                    object.boundingSphere = new Sphere().fromJSON( data.boundingSphere );

                }

                if ( data.boundingBox !== undefined ) {

                    object.boundingBox = new Box3().fromJSON( data.boundingBox );

                }

                break;

            case 'LOD':

                object = new LOD();

                break;

            case 'Line':

                object = new Line( getGeometry( data.geometry ), getMaterial( data.material ) );

                break;

            case 'LineLoop':

                object = new LineLoop( getGeometry( data.geometry ), getMaterial( data.material ) );

                break;

            case 'LineSegments':

                object = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );

                break;

            case 'PointCloud':
            case 'Points':

                object = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );

                break;

            case 'Sprite':

                object = new Sprite( getMaterial( data.material ) );

                break;

            case 'Group':

                object = new Group();

                break;

            case 'Bone':

                object = new Bone();

                break;

            default:

                object = new Object3D();

        }

        object.uuid = data.uuid;

        if ( data.name !== undefined ) object.name = data.name;

        if ( data.matrix !== undefined ) {

            object.matrix.fromArray( data.matrix );

            if ( data.matrixAutoUpdate !== undefined ) object.matrixAutoUpdate = data.matrixAutoUpdate;
            if ( object.matrixAutoUpdate ) object.matrix.decompose( object.position, object.quaternion, object.scale );

        } else {

            if ( data.position !== undefined ) object.position.fromArray( data.position );
            if ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );
            if ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion );
            if ( data.scale !== undefined ) object.scale.fromArray( data.scale );

        }

        if ( data.up !== undefined ) object.up.fromArray( data.up );

        if ( data.castShadow !== undefined ) object.castShadow = data.castShadow;
        if ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;

        if ( data.shadow ) {

            if ( data.shadow.intensity !== undefined ) object.shadow.intensity = data.shadow.intensity;
            if ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias;
            if ( data.shadow.normalBias !== undefined ) object.shadow.normalBias = data.shadow.normalBias;
            if ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius;
            if ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize );
            if ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera );

        }

        if ( data.visible !== undefined ) object.visible = data.visible;
        if ( data.frustumCulled !== undefined ) object.frustumCulled = data.frustumCulled;
        if ( data.renderOrder !== undefined ) object.renderOrder = data.renderOrder;
        if ( data.userData !== undefined ) object.userData = data.userData;
        if ( data.layers !== undefined ) object.layers.mask = data.layers;

        if ( data.children !== undefined ) {

            const children = data.children;

            for ( let i = 0; i < children.length; i ++ ) {

                object.add( this.parseObject( children[ i ], geometries, materials, textures, animations ) );

            }

        }

        if ( data.animations !== undefined ) {

            const objectAnimations = data.animations;

            for ( let i = 0; i < objectAnimations.length; i ++ ) {

                const uuid = objectAnimations[ i ];

                object.animations.push( animations[ uuid ] );

            }

        }

        if ( data.type === 'LOD' ) {

            if ( data.autoUpdate !== undefined ) object.autoUpdate = data.autoUpdate;

            const levels = data.levels;

            for ( let l = 0; l < levels.length; l ++ ) {

                const level = levels[ l ];
                const child = object.getObjectByProperty( 'uuid', level.object );

                if ( child !== undefined ) {

                    object.addLevel( child, level.distance, level.hysteresis );

                }

            }

        }

        return object;

    }

ObjectLoader.bindSkeletons(object: any, skeletons: any): void

Parameters:

  • object any
  • skeletons any

Returns: void

Calls:

  • Object.keys
  • object.traverse
  • console.warn
  • child.bind
Code
bindSkeletons( object, skeletons ) {

        if ( Object.keys( skeletons ).length === 0 ) return;

        object.traverse( function ( child ) {

            if ( child.isSkinnedMesh === true && child.skeleton !== undefined ) {

                const skeleton = skeletons[ child.skeleton ];

                if ( skeleton === undefined ) {

                    console.warn( 'THREE.ObjectLoader: No skeleton found with UUID:', child.skeleton );

                } else {

                    child.bind( skeleton, child.bindMatrix );

                }

            }

        } );

    }

ObjectLoader.bindLightTargets(object: any): void

Parameters:

  • object any

Returns: void

Calls:

  • object.traverse
  • object.getObjectByProperty
Code
bindLightTargets( object ) {

        object.traverse( function ( child ) {

            if ( child.isDirectionalLight || child.isSpotLight ) {

                const uuid = child.target;

                const target = object.getObjectByProperty( 'uuid', uuid );

                if ( target !== undefined ) {

                    child.target = target;

                } else {

                    child.target = new Object3D();

                }

            }

        } );

    }

loadImage(url: any): any

Parameters:

  • url any

Returns: any

Calls:

  • scope.manager.itemStart
  • loader.load
  • scope.manager.itemEnd
  • scope.manager.itemError
Code
function loadImage( url ) {

            scope.manager.itemStart( url );

            return loader.load( url, function () {

                scope.manager.itemEnd( url );

            }, undefined, function () {

                scope.manager.itemError( url );
                scope.manager.itemEnd( url );

            } );

        }

deserializeImage(image: any): any

Parameters:

  • image any

Returns: any

Calls:

  • /^(\/\/)|([a-z]+:(\/\/)?)/i.test
  • loadImage
  • getTypedArray (from ../utils.js)
Code
function deserializeImage( image ) {

            if ( typeof image === 'string' ) {

                const url = image;

                const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( url ) ? url : scope.resourcePath + url;

                return loadImage( path );

            } else {

                if ( image.data ) {

                    return {
                        data: getTypedArray( image.type, image.data ),
                        width: image.width,
                        height: image.height
                    };

                } else {

                    return null;

                }

            }

        }

deserializeImage(image: any): Promise<any>

Parameters:

  • image any

Returns: Promise<any>

Calls:

  • /^(\/\/)|([a-z]+:(\/\/)?)/i.test
  • loader.loadAsync
  • getTypedArray (from ../utils.js)
Code
async function deserializeImage( image ) {

            if ( typeof image === 'string' ) {

                const url = image;

                const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( url ) ? url : scope.resourcePath + url;

                return await loader.loadAsync( path );

            } else {

                if ( image.data ) {

                    return {
                        data: getTypedArray( image.type, image.data ),
                        width: image.width,
                        height: image.height
                    };

                } else {

                    return null;

                }

            }

        }

parseConstant(value: any, type: any): any

Parameters:

  • value any
  • type any

Returns: any

Calls:

  • console.warn
Code
function parseConstant( value, type ) {

            if ( typeof value === 'number' ) return value;

            console.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );

            return type[ value ];

        }

getGeometry(name: any): any

Parameters:

  • name any

Returns: any

Calls:

  • console.warn
Code
function getGeometry( name ) {

            if ( geometries[ name ] === undefined ) {

                console.warn( 'THREE.ObjectLoader: Undefined geometry', name );

            }

            return geometries[ name ];

        }

getMaterial(name: any): any

Parameters:

  • name any

Returns: any

Calls:

  • Array.isArray
  • console.warn
  • array.push
Code
function getMaterial( name ) {

            if ( name === undefined ) return undefined;

            if ( Array.isArray( name ) ) {

                const array = [];

                for ( let i = 0, l = name.length; i < l; i ++ ) {

                    const uuid = name[ i ];

                    if ( materials[ uuid ] === undefined ) {

                        console.warn( 'THREE.ObjectLoader: Undefined material', uuid );

                    }

                    array.push( materials[ uuid ] );

                }

                return array;

            }

            if ( materials[ name ] === undefined ) {

                console.warn( 'THREE.ObjectLoader: Undefined material', name );

            }

            return materials[ name ];

        }

getTexture(uuid: any): any

Parameters:

  • uuid any

Returns: any

Calls:

  • console.warn
Code
function getTexture( uuid ) {

            if ( textures[ uuid ] === undefined ) {

                console.warn( 'THREE.ObjectLoader: Undefined texture', uuid );

            }

            return textures[ uuid ];

        }

Classes

ObjectLoader

Class Code
class ObjectLoader extends Loader {

    /**
     * Constructs a new object loader.
     *
     * @param {LoadingManager} [manager] - The loading manager.
     */
    constructor( manager ) {

        super( manager );

    }

    /**
     * Starts loading from the given URL and pass the loaded 3D object to the `onLoad()` callback.
     *
     * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.
     * @param {function(Object3D)} onLoad - Executed when the loading process has been finished.
     * @param {onProgressCallback} onProgress - Executed while the loading is in progress.
     * @param {onErrorCallback} onError - Executed when errors occur.
     */
    load( url, onLoad, onProgress, onError ) {

        const scope = this;

        const path = ( this.path === '' ) ? LoaderUtils.extractUrlBase( url ) : this.path;
        this.resourcePath = this.resourcePath || path;

        const loader = new FileLoader( this.manager );
        loader.setPath( this.path );
        loader.setRequestHeader( this.requestHeader );
        loader.setWithCredentials( this.withCredentials );
        loader.load( url, function ( text ) {

            let json = null;

            try {

                json = JSON.parse( text );

            } catch ( error ) {

                if ( onError !== undefined ) onError( error );

                console.error( 'THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message );

                return;

            }

            const metadata = json.metadata;

            if ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {

                if ( onError !== undefined ) onError( new Error( 'THREE.ObjectLoader: Can\'t load ' + url ) );

                console.error( 'THREE.ObjectLoader: Can\'t load ' + url );
                return;

            }

            scope.parse( json, onLoad );

        }, onProgress, onError );

    }

    /**
     * Async version of {@link ObjectLoader#load}.
     *
     * @async
     * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.
     * @param {onProgressCallback} onProgress - Executed while the loading is in progress.
     * @return {Promise<Object3D>} A Promise that resolves with the loaded 3D object.
     */
    async loadAsync( url, onProgress ) {

        const scope = this;

        const path = ( this.path === '' ) ? LoaderUtils.extractUrlBase( url ) : this.path;
        this.resourcePath = this.resourcePath || path;

        const loader = new FileLoader( this.manager );
        loader.setPath( this.path );
        loader.setRequestHeader( this.requestHeader );
        loader.setWithCredentials( this.withCredentials );

        const text = await loader.loadAsync( url, onProgress );

        const json = JSON.parse( text );

        const metadata = json.metadata;

        if ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {

            throw new Error( 'THREE.ObjectLoader: Can\'t load ' + url );

        }

        return await scope.parseAsync( json );

    }

    /**
     * Parses the given JSON. This is used internally by {@link ObjectLoader#load}
     * but can also be used directly to parse a previously loaded JSON structure.
     *
     * @param {Object} json - The serialized 3D object.
     * @param {onLoad} onLoad - Executed when all resources (e.g. textures) have been fully loaded.
     * @return {Object3D} The parsed 3D object.
     */
    parse( json, onLoad ) {

        const animations = this.parseAnimations( json.animations );
        const shapes = this.parseShapes( json.shapes );
        const geometries = this.parseGeometries( json.geometries, shapes );

        const images = this.parseImages( json.images, function () {

            if ( onLoad !== undefined ) onLoad( object );

        } );

        const textures = this.parseTextures( json.textures, images );
        const materials = this.parseMaterials( json.materials, textures );

        const object = this.parseObject( json.object, geometries, materials, textures, animations );
        const skeletons = this.parseSkeletons( json.skeletons, object );

        this.bindSkeletons( object, skeletons );
        this.bindLightTargets( object );

        //

        if ( onLoad !== undefined ) {

            let hasImages = false;

            for ( const uuid in images ) {

                if ( images[ uuid ].data instanceof HTMLImageElement ) {

                    hasImages = true;
                    break;

                }

            }

            if ( hasImages === false ) onLoad( object );

        }

        return object;

    }

    /**
     * Async version of {@link ObjectLoader#parse}.
     *
     * @param {Object} json - The serialized 3D object.
     * @return {Promise<Object3D>} A Promise that resolves with the parsed 3D object.
     */
    async parseAsync( json ) {

        const animations = this.parseAnimations( json.animations );
        const shapes = this.parseShapes( json.shapes );
        const geometries = this.parseGeometries( json.geometries, shapes );

        const images = await this.parseImagesAsync( json.images );

        const textures = this.parseTextures( json.textures, images );
        const materials = this.parseMaterials( json.materials, textures );

        const object = this.parseObject( json.object, geometries, materials, textures, animations );
        const skeletons = this.parseSkeletons( json.skeletons, object );

        this.bindSkeletons( object, skeletons );
        this.bindLightTargets( object );

        return object;

    }

    // internals

    parseShapes( json ) {

        const shapes = {};

        if ( json !== undefined ) {

            for ( let i = 0, l = json.length; i < l; i ++ ) {

                const shape = new Shape().fromJSON( json[ i ] );

                shapes[ shape.uuid ] = shape;

            }

        }

        return shapes;

    }

    parseSkeletons( json, object ) {

        const skeletons = {};
        const bones = {};

        // generate bone lookup table

        object.traverse( function ( child ) {

            if ( child.isBone ) bones[ child.uuid ] = child;

        } );

        // create skeletons

        if ( json !== undefined ) {

            for ( let i = 0, l = json.length; i < l; i ++ ) {

                const skeleton = new Skeleton().fromJSON( json[ i ], bones );

                skeletons[ skeleton.uuid ] = skeleton;

            }

        }

        return skeletons;

    }

    parseGeometries( json, shapes ) {

        const geometries = {};

        if ( json !== undefined ) {

            const bufferGeometryLoader = new BufferGeometryLoader();

            for ( let i = 0, l = json.length; i < l; i ++ ) {

                let geometry;
                const data = json[ i ];

                switch ( data.type ) {

                    case 'BufferGeometry':
                    case 'InstancedBufferGeometry':

                        geometry = bufferGeometryLoader.parse( data );
                        break;

                    default:

                        if ( data.type in Geometries ) {

                            geometry = Geometries[ data.type ].fromJSON( data, shapes );

                        } else {

                            console.warn( `THREE.ObjectLoader: Unsupported geometry type "${ data.type }"` );

                        }

                }

                geometry.uuid = data.uuid;

                if ( data.name !== undefined ) geometry.name = data.name;
                if ( data.userData !== undefined ) geometry.userData = data.userData;

                geometries[ data.uuid ] = geometry;

            }

        }

        return geometries;

    }

    parseMaterials( json, textures ) {

        const cache = {}; // MultiMaterial
        const materials = {};

        if ( json !== undefined ) {

            const loader = new MaterialLoader();
            loader.setTextures( textures );

            for ( let i = 0, l = json.length; i < l; i ++ ) {

                const data = json[ i ];

                if ( cache[ data.uuid ] === undefined ) {

                    cache[ data.uuid ] = loader.parse( data );

                }

                materials[ data.uuid ] = cache[ data.uuid ];

            }

        }

        return materials;

    }

    parseAnimations( json ) {

        const animations = {};

        if ( json !== undefined ) {

            for ( let i = 0; i < json.length; i ++ ) {

                const data = json[ i ];

                const clip = AnimationClip.parse( data );

                animations[ clip.uuid ] = clip;

            }

        }

        return animations;

    }

    parseImages( json, onLoad ) {

        const scope = this;
        const images = {};

        let loader;

        function loadImage( url ) {

            scope.manager.itemStart( url );

            return loader.load( url, function () {

                scope.manager.itemEnd( url );

            }, undefined, function () {

                scope.manager.itemError( url );
                scope.manager.itemEnd( url );

            } );

        }

        function deserializeImage( image ) {

            if ( typeof image === 'string' ) {

                const url = image;

                const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( url ) ? url : scope.resourcePath + url;

                return loadImage( path );

            } else {

                if ( image.data ) {

                    return {
                        data: getTypedArray( image.type, image.data ),
                        width: image.width,
                        height: image.height
                    };

                } else {

                    return null;

                }

            }

        }

        if ( json !== undefined && json.length > 0 ) {

            const manager = new LoadingManager( onLoad );

            loader = new ImageLoader( manager );
            loader.setCrossOrigin( this.crossOrigin );

            for ( let i = 0, il = json.length; i < il; i ++ ) {

                const image = json[ i ];
                const url = image.url;

                if ( Array.isArray( url ) ) {

                    // load array of images e.g CubeTexture

                    const imageArray = [];

                    for ( let j = 0, jl = url.length; j < jl; j ++ ) {

                        const currentUrl = url[ j ];

                        const deserializedImage = deserializeImage( currentUrl );

                        if ( deserializedImage !== null ) {

                            if ( deserializedImage instanceof HTMLImageElement ) {

                                imageArray.push( deserializedImage );

                            } else {

                                // special case: handle array of data textures for cube textures

                                imageArray.push( new DataTexture( deserializedImage.data, deserializedImage.width, deserializedImage.height ) );

                            }

                        }

                    }

                    images[ image.uuid ] = new Source( imageArray );

                } else {

                    // load single image

                    const deserializedImage = deserializeImage( image.url );
                    images[ image.uuid ] = new Source( deserializedImage );


                }

            }

        }

        return images;

    }

    async parseImagesAsync( json ) {

        const scope = this;
        const images = {};

        let loader;

        async function deserializeImage( image ) {

            if ( typeof image === 'string' ) {

                const url = image;

                const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( url ) ? url : scope.resourcePath + url;

                return await loader.loadAsync( path );

            } else {

                if ( image.data ) {

                    return {
                        data: getTypedArray( image.type, image.data ),
                        width: image.width,
                        height: image.height
                    };

                } else {

                    return null;

                }

            }

        }

        if ( json !== undefined && json.length > 0 ) {

            loader = new ImageLoader( this.manager );
            loader.setCrossOrigin( this.crossOrigin );

            for ( let i = 0, il = json.length; i < il; i ++ ) {

                const image = json[ i ];
                const url = image.url;

                if ( Array.isArray( url ) ) {

                    // load array of images e.g CubeTexture

                    const imageArray = [];

                    for ( let j = 0, jl = url.length; j < jl; j ++ ) {

                        const currentUrl = url[ j ];

                        const deserializedImage = await deserializeImage( currentUrl );

                        if ( deserializedImage !== null ) {

                            if ( deserializedImage instanceof HTMLImageElement ) {

                                imageArray.push( deserializedImage );

                            } else {

                                // special case: handle array of data textures for cube textures

                                imageArray.push( new DataTexture( deserializedImage.data, deserializedImage.width, deserializedImage.height ) );

                            }

                        }

                    }

                    images[ image.uuid ] = new Source( imageArray );

                } else {

                    // load single image

                    const deserializedImage = await deserializeImage( image.url );
                    images[ image.uuid ] = new Source( deserializedImage );

                }

            }

        }

        return images;

    }

    parseTextures( json, images ) {

        function parseConstant( value, type ) {

            if ( typeof value === 'number' ) return value;

            console.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );

            return type[ value ];

        }

        const textures = {};

        if ( json !== undefined ) {

            for ( let i = 0, l = json.length; i < l; i ++ ) {

                const data = json[ i ];

                if ( data.image === undefined ) {

                    console.warn( 'THREE.ObjectLoader: No "image" specified for', data.uuid );

                }

                if ( images[ data.image ] === undefined ) {

                    console.warn( 'THREE.ObjectLoader: Undefined image', data.image );

                }

                const source = images[ data.image ];
                const image = source.data;

                let texture;

                if ( Array.isArray( image ) ) {

                    texture = new CubeTexture();

                    if ( image.length === 6 ) texture.needsUpdate = true;

                } else {

                    if ( image && image.data ) {

                        texture = new DataTexture();

                    } else {

                        texture = new Texture();

                    }

                    if ( image ) texture.needsUpdate = true; // textures can have undefined image data

                }

                texture.source = source;

                texture.uuid = data.uuid;

                if ( data.name !== undefined ) texture.name = data.name;

                if ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TEXTURE_MAPPING );
                if ( data.channel !== undefined ) texture.channel = data.channel;

                if ( data.offset !== undefined ) texture.offset.fromArray( data.offset );
                if ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat );
                if ( data.center !== undefined ) texture.center.fromArray( data.center );
                if ( data.rotation !== undefined ) texture.rotation = data.rotation;

                if ( data.wrap !== undefined ) {

                    texture.wrapS = parseConstant( data.wrap[ 0 ], TEXTURE_WRAPPING );
                    texture.wrapT = parseConstant( data.wrap[ 1 ], TEXTURE_WRAPPING );

                }

                if ( data.format !== undefined ) texture.format = data.format;
                if ( data.internalFormat !== undefined ) texture.internalFormat = data.internalFormat;
                if ( data.type !== undefined ) texture.type = data.type;
                if ( data.colorSpace !== undefined ) texture.colorSpace = data.colorSpace;

                if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TEXTURE_FILTER );
                if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TEXTURE_FILTER );
                if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;

                if ( data.flipY !== undefined ) texture.flipY = data.flipY;

                if ( data.generateMipmaps !== undefined ) texture.generateMipmaps = data.generateMipmaps;
                if ( data.premultiplyAlpha !== undefined ) texture.premultiplyAlpha = data.premultiplyAlpha;
                if ( data.unpackAlignment !== undefined ) texture.unpackAlignment = data.unpackAlignment;
                if ( data.compareFunction !== undefined ) texture.compareFunction = data.compareFunction;

                if ( data.userData !== undefined ) texture.userData = data.userData;

                textures[ data.uuid ] = texture;

            }

        }

        return textures;

    }

    parseObject( data, geometries, materials, textures, animations ) {

        let object;

        function getGeometry( name ) {

            if ( geometries[ name ] === undefined ) {

                console.warn( 'THREE.ObjectLoader: Undefined geometry', name );

            }

            return geometries[ name ];

        }

        function getMaterial( name ) {

            if ( name === undefined ) return undefined;

            if ( Array.isArray( name ) ) {

                const array = [];

                for ( let i = 0, l = name.length; i < l; i ++ ) {

                    const uuid = name[ i ];

                    if ( materials[ uuid ] === undefined ) {

                        console.warn( 'THREE.ObjectLoader: Undefined material', uuid );

                    }

                    array.push( materials[ uuid ] );

                }

                return array;

            }

            if ( materials[ name ] === undefined ) {

                console.warn( 'THREE.ObjectLoader: Undefined material', name );

            }

            return materials[ name ];

        }

        function getTexture( uuid ) {

            if ( textures[ uuid ] === undefined ) {

                console.warn( 'THREE.ObjectLoader: Undefined texture', uuid );

            }

            return textures[ uuid ];

        }

        let geometry, material;

        switch ( data.type ) {

            case 'Scene':

                object = new Scene();

                if ( data.background !== undefined ) {

                    if ( Number.isInteger( data.background ) ) {

                        object.background = new Color( data.background );

                    } else {

                        object.background = getTexture( data.background );

                    }

                }

                if ( data.environment !== undefined ) {

                    object.environment = getTexture( data.environment );

                }

                if ( data.fog !== undefined ) {

                    if ( data.fog.type === 'Fog' ) {

                        object.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );

                    } else if ( data.fog.type === 'FogExp2' ) {

                        object.fog = new FogExp2( data.fog.color, data.fog.density );

                    }

                    if ( data.fog.name !== '' ) {

                        object.fog.name = data.fog.name;

                    }

                }

                if ( data.backgroundBlurriness !== undefined ) object.backgroundBlurriness = data.backgroundBlurriness;
                if ( data.backgroundIntensity !== undefined ) object.backgroundIntensity = data.backgroundIntensity;
                if ( data.backgroundRotation !== undefined ) object.backgroundRotation.fromArray( data.backgroundRotation );

                if ( data.environmentIntensity !== undefined ) object.environmentIntensity = data.environmentIntensity;
                if ( data.environmentRotation !== undefined ) object.environmentRotation.fromArray( data.environmentRotation );

                break;

            case 'PerspectiveCamera':

                object = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );

                if ( data.focus !== undefined ) object.focus = data.focus;
                if ( data.zoom !== undefined ) object.zoom = data.zoom;
                if ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge;
                if ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset;
                if ( data.view !== undefined ) object.view = Object.assign( {}, data.view );

                break;

            case 'OrthographicCamera':

                object = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );

                if ( data.zoom !== undefined ) object.zoom = data.zoom;
                if ( data.view !== undefined ) object.view = Object.assign( {}, data.view );

                break;

            case 'AmbientLight':

                object = new AmbientLight( data.color, data.intensity );

                break;

            case 'DirectionalLight':

                object = new DirectionalLight( data.color, data.intensity );
                object.target = data.target || '';

                break;

            case 'PointLight':

                object = new PointLight( data.color, data.intensity, data.distance, data.decay );

                break;

            case 'RectAreaLight':

                object = new RectAreaLight( data.color, data.intensity, data.width, data.height );

                break;

            case 'SpotLight':

                object = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );
                object.target = data.target || '';

                break;

            case 'HemisphereLight':

                object = new HemisphereLight( data.color, data.groundColor, data.intensity );

                break;

            case 'LightProbe':

                object = new LightProbe().fromJSON( data );

                break;

            case 'SkinnedMesh':

                geometry = getGeometry( data.geometry );
                material = getMaterial( data.material );

                object = new SkinnedMesh( geometry, material );

                if ( data.bindMode !== undefined ) object.bindMode = data.bindMode;
                if ( data.bindMatrix !== undefined ) object.bindMatrix.fromArray( data.bindMatrix );
                if ( data.skeleton !== undefined ) object.skeleton = data.skeleton;

                break;

            case 'Mesh':

                geometry = getGeometry( data.geometry );
                material = getMaterial( data.material );

                object = new Mesh( geometry, material );

                break;

            case 'InstancedMesh':

                geometry = getGeometry( data.geometry );
                material = getMaterial( data.material );
                const count = data.count;
                const instanceMatrix = data.instanceMatrix;
                const instanceColor = data.instanceColor;

                object = new InstancedMesh( geometry, material, count );
                object.instanceMatrix = new InstancedBufferAttribute( new Float32Array( instanceMatrix.array ), 16 );
                if ( instanceColor !== undefined ) object.instanceColor = new InstancedBufferAttribute( new Float32Array( instanceColor.array ), instanceColor.itemSize );

                break;

            case 'BatchedMesh':

                geometry = getGeometry( data.geometry );
                material = getMaterial( data.material );

                object = new BatchedMesh( data.maxInstanceCount, data.maxVertexCount, data.maxIndexCount, material );
                object.geometry = geometry;
                object.perObjectFrustumCulled = data.perObjectFrustumCulled;
                object.sortObjects = data.sortObjects;

                object._drawRanges = data.drawRanges;
                object._reservedRanges = data.reservedRanges;

                object._geometryInfo = data.geometryInfo.map( info => {

                    let box = null;
                    let sphere = null;
                    if ( info.boundingBox !== undefined ) {

                        box = new Box3().fromJSON( info.boundingBox );

                    }

                    if ( info.boundingSphere !== undefined ) {

                        sphere = new Sphere().fromJSON( info.boundingSphere );

                    }

                    return {
                        ...info,
                        boundingBox: box,
                        boundingSphere: sphere
                    };

                } );
                object._instanceInfo = data.instanceInfo;

                object._availableInstanceIds = data._availableInstanceIds;
                object._availableGeometryIds = data._availableGeometryIds;

                object._nextIndexStart = data.nextIndexStart;
                object._nextVertexStart = data.nextVertexStart;
                object._geometryCount = data.geometryCount;

                object._maxInstanceCount = data.maxInstanceCount;
                object._maxVertexCount = data.maxVertexCount;
                object._maxIndexCount = data.maxIndexCount;

                object._geometryInitialized = data.geometryInitialized;

                object._matricesTexture = getTexture( data.matricesTexture.uuid );

                object._indirectTexture = getTexture( data.indirectTexture.uuid );

                if ( data.colorsTexture !== undefined ) {

                    object._colorsTexture = getTexture( data.colorsTexture.uuid );

                }

                if ( data.boundingSphere !== undefined ) {

                    object.boundingSphere = new Sphere().fromJSON( data.boundingSphere );

                }

                if ( data.boundingBox !== undefined ) {

                    object.boundingBox = new Box3().fromJSON( data.boundingBox );

                }

                break;

            case 'LOD':

                object = new LOD();

                break;

            case 'Line':

                object = new Line( getGeometry( data.geometry ), getMaterial( data.material ) );

                break;

            case 'LineLoop':

                object = new LineLoop( getGeometry( data.geometry ), getMaterial( data.material ) );

                break;

            case 'LineSegments':

                object = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );

                break;

            case 'PointCloud':
            case 'Points':

                object = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );

                break;

            case 'Sprite':

                object = new Sprite( getMaterial( data.material ) );

                break;

            case 'Group':

                object = new Group();

                break;

            case 'Bone':

                object = new Bone();

                break;

            default:

                object = new Object3D();

        }

        object.uuid = data.uuid;

        if ( data.name !== undefined ) object.name = data.name;

        if ( data.matrix !== undefined ) {

            object.matrix.fromArray( data.matrix );

            if ( data.matrixAutoUpdate !== undefined ) object.matrixAutoUpdate = data.matrixAutoUpdate;
            if ( object.matrixAutoUpdate ) object.matrix.decompose( object.position, object.quaternion, object.scale );

        } else {

            if ( data.position !== undefined ) object.position.fromArray( data.position );
            if ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );
            if ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion );
            if ( data.scale !== undefined ) object.scale.fromArray( data.scale );

        }

        if ( data.up !== undefined ) object.up.fromArray( data.up );

        if ( data.castShadow !== undefined ) object.castShadow = data.castShadow;
        if ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;

        if ( data.shadow ) {

            if ( data.shadow.intensity !== undefined ) object.shadow.intensity = data.shadow.intensity;
            if ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias;
            if ( data.shadow.normalBias !== undefined ) object.shadow.normalBias = data.shadow.normalBias;
            if ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius;
            if ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize );
            if ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera );

        }

        if ( data.visible !== undefined ) object.visible = data.visible;
        if ( data.frustumCulled !== undefined ) object.frustumCulled = data.frustumCulled;
        if ( data.renderOrder !== undefined ) object.renderOrder = data.renderOrder;
        if ( data.userData !== undefined ) object.userData = data.userData;
        if ( data.layers !== undefined ) object.layers.mask = data.layers;

        if ( data.children !== undefined ) {

            const children = data.children;

            for ( let i = 0; i < children.length; i ++ ) {

                object.add( this.parseObject( children[ i ], geometries, materials, textures, animations ) );

            }

        }

        if ( data.animations !== undefined ) {

            const objectAnimations = data.animations;

            for ( let i = 0; i < objectAnimations.length; i ++ ) {

                const uuid = objectAnimations[ i ];

                object.animations.push( animations[ uuid ] );

            }

        }

        if ( data.type === 'LOD' ) {

            if ( data.autoUpdate !== undefined ) object.autoUpdate = data.autoUpdate;

            const levels = data.levels;

            for ( let l = 0; l < levels.length; l ++ ) {

                const level = levels[ l ];
                const child = object.getObjectByProperty( 'uuid', level.object );

                if ( child !== undefined ) {

                    object.addLevel( child, level.distance, level.hysteresis );

                }

            }

        }

        return object;

    }

    bindSkeletons( object, skeletons ) {

        if ( Object.keys( skeletons ).length === 0 ) return;

        object.traverse( function ( child ) {

            if ( child.isSkinnedMesh === true && child.skeleton !== undefined ) {

                const skeleton = skeletons[ child.skeleton ];

                if ( skeleton === undefined ) {

                    console.warn( 'THREE.ObjectLoader: No skeleton found with UUID:', child.skeleton );

                } else {

                    child.bind( skeleton, child.bindMatrix );

                }

            }

        } );

    }

    bindLightTargets( object ) {

        object.traverse( function ( child ) {

            if ( child.isDirectionalLight || child.isSpotLight ) {

                const uuid = child.target;

                const target = object.getObjectByProperty( 'uuid', uuid );

                if ( target !== undefined ) {

                    child.target = target;

                } else {

                    child.target = new Object3D();

                }

            }

        } );

    }

}

Methods

load(url: string, onLoad: (arg0: Object3D) => any, onProgress: onProgressCallback, onError: onErrorCallback): void
Code
load( url, onLoad, onProgress, onError ) {

        const scope = this;

        const path = ( this.path === '' ) ? LoaderUtils.extractUrlBase( url ) : this.path;
        this.resourcePath = this.resourcePath || path;

        const loader = new FileLoader( this.manager );
        loader.setPath( this.path );
        loader.setRequestHeader( this.requestHeader );
        loader.setWithCredentials( this.withCredentials );
        loader.load( url, function ( text ) {

            let json = null;

            try {

                json = JSON.parse( text );

            } catch ( error ) {

                if ( onError !== undefined ) onError( error );

                console.error( 'THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message );

                return;

            }

            const metadata = json.metadata;

            if ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {

                if ( onError !== undefined ) onError( new Error( 'THREE.ObjectLoader: Can\'t load ' + url ) );

                console.error( 'THREE.ObjectLoader: Can\'t load ' + url );
                return;

            }

            scope.parse( json, onLoad );

        }, onProgress, onError );

    }
loadAsync(url: string, onProgress: onProgressCallback): Promise<Object3D>
Code
async loadAsync( url, onProgress ) {

        const scope = this;

        const path = ( this.path === '' ) ? LoaderUtils.extractUrlBase( url ) : this.path;
        this.resourcePath = this.resourcePath || path;

        const loader = new FileLoader( this.manager );
        loader.setPath( this.path );
        loader.setRequestHeader( this.requestHeader );
        loader.setWithCredentials( this.withCredentials );

        const text = await loader.loadAsync( url, onProgress );

        const json = JSON.parse( text );

        const metadata = json.metadata;

        if ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {

            throw new Error( 'THREE.ObjectLoader: Can\'t load ' + url );

        }

        return await scope.parseAsync( json );

    }
parse(json: any, onLoad: any): Object3D
Code
parse( json, onLoad ) {

        const animations = this.parseAnimations( json.animations );
        const shapes = this.parseShapes( json.shapes );
        const geometries = this.parseGeometries( json.geometries, shapes );

        const images = this.parseImages( json.images, function () {

            if ( onLoad !== undefined ) onLoad( object );

        } );

        const textures = this.parseTextures( json.textures, images );
        const materials = this.parseMaterials( json.materials, textures );

        const object = this.parseObject( json.object, geometries, materials, textures, animations );
        const skeletons = this.parseSkeletons( json.skeletons, object );

        this.bindSkeletons( object, skeletons );
        this.bindLightTargets( object );

        //

        if ( onLoad !== undefined ) {

            let hasImages = false;

            for ( const uuid in images ) {

                if ( images[ uuid ].data instanceof HTMLImageElement ) {

                    hasImages = true;
                    break;

                }

            }

            if ( hasImages === false ) onLoad( object );

        }

        return object;

    }
parseAsync(json: any): Promise<Object3D>
Code
async parseAsync( json ) {

        const animations = this.parseAnimations( json.animations );
        const shapes = this.parseShapes( json.shapes );
        const geometries = this.parseGeometries( json.geometries, shapes );

        const images = await this.parseImagesAsync( json.images );

        const textures = this.parseTextures( json.textures, images );
        const materials = this.parseMaterials( json.materials, textures );

        const object = this.parseObject( json.object, geometries, materials, textures, animations );
        const skeletons = this.parseSkeletons( json.skeletons, object );

        this.bindSkeletons( object, skeletons );
        this.bindLightTargets( object );

        return object;

    }
parseShapes(json: any): {}
Code
parseShapes( json ) {

        const shapes = {};

        if ( json !== undefined ) {

            for ( let i = 0, l = json.length; i < l; i ++ ) {

                const shape = new Shape().fromJSON( json[ i ] );

                shapes[ shape.uuid ] = shape;

            }

        }

        return shapes;

    }
parseSkeletons(json: any, object: any): {}
Code
parseSkeletons( json, object ) {

        const skeletons = {};
        const bones = {};

        // generate bone lookup table

        object.traverse( function ( child ) {

            if ( child.isBone ) bones[ child.uuid ] = child;

        } );

        // create skeletons

        if ( json !== undefined ) {

            for ( let i = 0, l = json.length; i < l; i ++ ) {

                const skeleton = new Skeleton().fromJSON( json[ i ], bones );

                skeletons[ skeleton.uuid ] = skeleton;

            }

        }

        return skeletons;

    }
parseGeometries(json: any, shapes: any): {}
Code
parseGeometries( json, shapes ) {

        const geometries = {};

        if ( json !== undefined ) {

            const bufferGeometryLoader = new BufferGeometryLoader();

            for ( let i = 0, l = json.length; i < l; i ++ ) {

                let geometry;
                const data = json[ i ];

                switch ( data.type ) {

                    case 'BufferGeometry':
                    case 'InstancedBufferGeometry':

                        geometry = bufferGeometryLoader.parse( data );
                        break;

                    default:

                        if ( data.type in Geometries ) {

                            geometry = Geometries[ data.type ].fromJSON( data, shapes );

                        } else {

                            console.warn( `THREE.ObjectLoader: Unsupported geometry type "${ data.type }"` );

                        }

                }

                geometry.uuid = data.uuid;

                if ( data.name !== undefined ) geometry.name = data.name;
                if ( data.userData !== undefined ) geometry.userData = data.userData;

                geometries[ data.uuid ] = geometry;

            }

        }

        return geometries;

    }
parseMaterials(json: any, textures: any): {}
Code
parseMaterials( json, textures ) {

        const cache = {}; // MultiMaterial
        const materials = {};

        if ( json !== undefined ) {

            const loader = new MaterialLoader();
            loader.setTextures( textures );

            for ( let i = 0, l = json.length; i < l; i ++ ) {

                const data = json[ i ];

                if ( cache[ data.uuid ] === undefined ) {

                    cache[ data.uuid ] = loader.parse( data );

                }

                materials[ data.uuid ] = cache[ data.uuid ];

            }

        }

        return materials;

    }
parseAnimations(json: any): {}
Code
parseAnimations( json ) {

        const animations = {};

        if ( json !== undefined ) {

            for ( let i = 0; i < json.length; i ++ ) {

                const data = json[ i ];

                const clip = AnimationClip.parse( data );

                animations[ clip.uuid ] = clip;

            }

        }

        return animations;

    }
parseImages(json: any, onLoad: any): {}
Code
parseImages( json, onLoad ) {

        const scope = this;
        const images = {};

        let loader;

        function loadImage( url ) {

            scope.manager.itemStart( url );

            return loader.load( url, function () {

                scope.manager.itemEnd( url );

            }, undefined, function () {

                scope.manager.itemError( url );
                scope.manager.itemEnd( url );

            } );

        }

        function deserializeImage( image ) {

            if ( typeof image === 'string' ) {

                const url = image;

                const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( url ) ? url : scope.resourcePath + url;

                return loadImage( path );

            } else {

                if ( image.data ) {

                    return {
                        data: getTypedArray( image.type, image.data ),
                        width: image.width,
                        height: image.height
                    };

                } else {

                    return null;

                }

            }

        }

        if ( json !== undefined && json.length > 0 ) {

            const manager = new LoadingManager( onLoad );

            loader = new ImageLoader( manager );
            loader.setCrossOrigin( this.crossOrigin );

            for ( let i = 0, il = json.length; i < il; i ++ ) {

                const image = json[ i ];
                const url = image.url;

                if ( Array.isArray( url ) ) {

                    // load array of images e.g CubeTexture

                    const imageArray = [];

                    for ( let j = 0, jl = url.length; j < jl; j ++ ) {

                        const currentUrl = url[ j ];

                        const deserializedImage = deserializeImage( currentUrl );

                        if ( deserializedImage !== null ) {

                            if ( deserializedImage instanceof HTMLImageElement ) {

                                imageArray.push( deserializedImage );

                            } else {

                                // special case: handle array of data textures for cube textures

                                imageArray.push( new DataTexture( deserializedImage.data, deserializedImage.width, deserializedImage.height ) );

                            }

                        }

                    }

                    images[ image.uuid ] = new Source( imageArray );

                } else {

                    // load single image

                    const deserializedImage = deserializeImage( image.url );
                    images[ image.uuid ] = new Source( deserializedImage );


                }

            }

        }

        return images;

    }
parseImagesAsync(json: any): Promise<{}>
Code
async parseImagesAsync( json ) {

        const scope = this;
        const images = {};

        let loader;

        async function deserializeImage( image ) {

            if ( typeof image === 'string' ) {

                const url = image;

                const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( url ) ? url : scope.resourcePath + url;

                return await loader.loadAsync( path );

            } else {

                if ( image.data ) {

                    return {
                        data: getTypedArray( image.type, image.data ),
                        width: image.width,
                        height: image.height
                    };

                } else {

                    return null;

                }

            }

        }

        if ( json !== undefined && json.length > 0 ) {

            loader = new ImageLoader( this.manager );
            loader.setCrossOrigin( this.crossOrigin );

            for ( let i = 0, il = json.length; i < il; i ++ ) {

                const image = json[ i ];
                const url = image.url;

                if ( Array.isArray( url ) ) {

                    // load array of images e.g CubeTexture

                    const imageArray = [];

                    for ( let j = 0, jl = url.length; j < jl; j ++ ) {

                        const currentUrl = url[ j ];

                        const deserializedImage = await deserializeImage( currentUrl );

                        if ( deserializedImage !== null ) {

                            if ( deserializedImage instanceof HTMLImageElement ) {

                                imageArray.push( deserializedImage );

                            } else {

                                // special case: handle array of data textures for cube textures

                                imageArray.push( new DataTexture( deserializedImage.data, deserializedImage.width, deserializedImage.height ) );

                            }

                        }

                    }

                    images[ image.uuid ] = new Source( imageArray );

                } else {

                    // load single image

                    const deserializedImage = await deserializeImage( image.url );
                    images[ image.uuid ] = new Source( deserializedImage );

                }

            }

        }

        return images;

    }
parseTextures(json: any, images: any): {}
Code
parseTextures( json, images ) {

        function parseConstant( value, type ) {

            if ( typeof value === 'number' ) return value;

            console.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );

            return type[ value ];

        }

        const textures = {};

        if ( json !== undefined ) {

            for ( let i = 0, l = json.length; i < l; i ++ ) {

                const data = json[ i ];

                if ( data.image === undefined ) {

                    console.warn( 'THREE.ObjectLoader: No "image" specified for', data.uuid );

                }

                if ( images[ data.image ] === undefined ) {

                    console.warn( 'THREE.ObjectLoader: Undefined image', data.image );

                }

                const source = images[ data.image ];
                const image = source.data;

                let texture;

                if ( Array.isArray( image ) ) {

                    texture = new CubeTexture();

                    if ( image.length === 6 ) texture.needsUpdate = true;

                } else {

                    if ( image && image.data ) {

                        texture = new DataTexture();

                    } else {

                        texture = new Texture();

                    }

                    if ( image ) texture.needsUpdate = true; // textures can have undefined image data

                }

                texture.source = source;

                texture.uuid = data.uuid;

                if ( data.name !== undefined ) texture.name = data.name;

                if ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TEXTURE_MAPPING );
                if ( data.channel !== undefined ) texture.channel = data.channel;

                if ( data.offset !== undefined ) texture.offset.fromArray( data.offset );
                if ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat );
                if ( data.center !== undefined ) texture.center.fromArray( data.center );
                if ( data.rotation !== undefined ) texture.rotation = data.rotation;

                if ( data.wrap !== undefined ) {

                    texture.wrapS = parseConstant( data.wrap[ 0 ], TEXTURE_WRAPPING );
                    texture.wrapT = parseConstant( data.wrap[ 1 ], TEXTURE_WRAPPING );

                }

                if ( data.format !== undefined ) texture.format = data.format;
                if ( data.internalFormat !== undefined ) texture.internalFormat = data.internalFormat;
                if ( data.type !== undefined ) texture.type = data.type;
                if ( data.colorSpace !== undefined ) texture.colorSpace = data.colorSpace;

                if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TEXTURE_FILTER );
                if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TEXTURE_FILTER );
                if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy;

                if ( data.flipY !== undefined ) texture.flipY = data.flipY;

                if ( data.generateMipmaps !== undefined ) texture.generateMipmaps = data.generateMipmaps;
                if ( data.premultiplyAlpha !== undefined ) texture.premultiplyAlpha = data.premultiplyAlpha;
                if ( data.unpackAlignment !== undefined ) texture.unpackAlignment = data.unpackAlignment;
                if ( data.compareFunction !== undefined ) texture.compareFunction = data.compareFunction;

                if ( data.userData !== undefined ) texture.userData = data.userData;

                textures[ data.uuid ] = texture;

            }

        }

        return textures;

    }
parseObject(data: any, geometries: any, materials: any, textures: any, animations: any): Object3D | Mesh | PerspectiveCamera | Scene | Sprite | LOD | SkinnedMesh | InstancedMesh | ... 10 more ... | AmbientLight
Code
parseObject( data, geometries, materials, textures, animations ) {

        let object;

        function getGeometry( name ) {

            if ( geometries[ name ] === undefined ) {

                console.warn( 'THREE.ObjectLoader: Undefined geometry', name );

            }

            return geometries[ name ];

        }

        function getMaterial( name ) {

            if ( name === undefined ) return undefined;

            if ( Array.isArray( name ) ) {

                const array = [];

                for ( let i = 0, l = name.length; i < l; i ++ ) {

                    const uuid = name[ i ];

                    if ( materials[ uuid ] === undefined ) {

                        console.warn( 'THREE.ObjectLoader: Undefined material', uuid );

                    }

                    array.push( materials[ uuid ] );

                }

                return array;

            }

            if ( materials[ name ] === undefined ) {

                console.warn( 'THREE.ObjectLoader: Undefined material', name );

            }

            return materials[ name ];

        }

        function getTexture( uuid ) {

            if ( textures[ uuid ] === undefined ) {

                console.warn( 'THREE.ObjectLoader: Undefined texture', uuid );

            }

            return textures[ uuid ];

        }

        let geometry, material;

        switch ( data.type ) {

            case 'Scene':

                object = new Scene();

                if ( data.background !== undefined ) {

                    if ( Number.isInteger( data.background ) ) {

                        object.background = new Color( data.background );

                    } else {

                        object.background = getTexture( data.background );

                    }

                }

                if ( data.environment !== undefined ) {

                    object.environment = getTexture( data.environment );

                }

                if ( data.fog !== undefined ) {

                    if ( data.fog.type === 'Fog' ) {

                        object.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );

                    } else if ( data.fog.type === 'FogExp2' ) {

                        object.fog = new FogExp2( data.fog.color, data.fog.density );

                    }

                    if ( data.fog.name !== '' ) {

                        object.fog.name = data.fog.name;

                    }

                }

                if ( data.backgroundBlurriness !== undefined ) object.backgroundBlurriness = data.backgroundBlurriness;
                if ( data.backgroundIntensity !== undefined ) object.backgroundIntensity = data.backgroundIntensity;
                if ( data.backgroundRotation !== undefined ) object.backgroundRotation.fromArray( data.backgroundRotation );

                if ( data.environmentIntensity !== undefined ) object.environmentIntensity = data.environmentIntensity;
                if ( data.environmentRotation !== undefined ) object.environmentRotation.fromArray( data.environmentRotation );

                break;

            case 'PerspectiveCamera':

                object = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );

                if ( data.focus !== undefined ) object.focus = data.focus;
                if ( data.zoom !== undefined ) object.zoom = data.zoom;
                if ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge;
                if ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset;
                if ( data.view !== undefined ) object.view = Object.assign( {}, data.view );

                break;

            case 'OrthographicCamera':

                object = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );

                if ( data.zoom !== undefined ) object.zoom = data.zoom;
                if ( data.view !== undefined ) object.view = Object.assign( {}, data.view );

                break;

            case 'AmbientLight':

                object = new AmbientLight( data.color, data.intensity );

                break;

            case 'DirectionalLight':

                object = new DirectionalLight( data.color, data.intensity );
                object.target = data.target || '';

                break;

            case 'PointLight':

                object = new PointLight( data.color, data.intensity, data.distance, data.decay );

                break;

            case 'RectAreaLight':

                object = new RectAreaLight( data.color, data.intensity, data.width, data.height );

                break;

            case 'SpotLight':

                object = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );
                object.target = data.target || '';

                break;

            case 'HemisphereLight':

                object = new HemisphereLight( data.color, data.groundColor, data.intensity );

                break;

            case 'LightProbe':

                object = new LightProbe().fromJSON( data );

                break;

            case 'SkinnedMesh':

                geometry = getGeometry( data.geometry );
                material = getMaterial( data.material );

                object = new SkinnedMesh( geometry, material );

                if ( data.bindMode !== undefined ) object.bindMode = data.bindMode;
                if ( data.bindMatrix !== undefined ) object.bindMatrix.fromArray( data.bindMatrix );
                if ( data.skeleton !== undefined ) object.skeleton = data.skeleton;

                break;

            case 'Mesh':

                geometry = getGeometry( data.geometry );
                material = getMaterial( data.material );

                object = new Mesh( geometry, material );

                break;

            case 'InstancedMesh':

                geometry = getGeometry( data.geometry );
                material = getMaterial( data.material );
                const count = data.count;
                const instanceMatrix = data.instanceMatrix;
                const instanceColor = data.instanceColor;

                object = new InstancedMesh( geometry, material, count );
                object.instanceMatrix = new InstancedBufferAttribute( new Float32Array( instanceMatrix.array ), 16 );
                if ( instanceColor !== undefined ) object.instanceColor = new InstancedBufferAttribute( new Float32Array( instanceColor.array ), instanceColor.itemSize );

                break;

            case 'BatchedMesh':

                geometry = getGeometry( data.geometry );
                material = getMaterial( data.material );

                object = new BatchedMesh( data.maxInstanceCount, data.maxVertexCount, data.maxIndexCount, material );
                object.geometry = geometry;
                object.perObjectFrustumCulled = data.perObjectFrustumCulled;
                object.sortObjects = data.sortObjects;

                object._drawRanges = data.drawRanges;
                object._reservedRanges = data.reservedRanges;

                object._geometryInfo = data.geometryInfo.map( info => {

                    let box = null;
                    let sphere = null;
                    if ( info.boundingBox !== undefined ) {

                        box = new Box3().fromJSON( info.boundingBox );

                    }

                    if ( info.boundingSphere !== undefined ) {

                        sphere = new Sphere().fromJSON( info.boundingSphere );

                    }

                    return {
                        ...info,
                        boundingBox: box,
                        boundingSphere: sphere
                    };

                } );
                object._instanceInfo = data.instanceInfo;

                object._availableInstanceIds = data._availableInstanceIds;
                object._availableGeometryIds = data._availableGeometryIds;

                object._nextIndexStart = data.nextIndexStart;
                object._nextVertexStart = data.nextVertexStart;
                object._geometryCount = data.geometryCount;

                object._maxInstanceCount = data.maxInstanceCount;
                object._maxVertexCount = data.maxVertexCount;
                object._maxIndexCount = data.maxIndexCount;

                object._geometryInitialized = data.geometryInitialized;

                object._matricesTexture = getTexture( data.matricesTexture.uuid );

                object._indirectTexture = getTexture( data.indirectTexture.uuid );

                if ( data.colorsTexture !== undefined ) {

                    object._colorsTexture = getTexture( data.colorsTexture.uuid );

                }

                if ( data.boundingSphere !== undefined ) {

                    object.boundingSphere = new Sphere().fromJSON( data.boundingSphere );

                }

                if ( data.boundingBox !== undefined ) {

                    object.boundingBox = new Box3().fromJSON( data.boundingBox );

                }

                break;

            case 'LOD':

                object = new LOD();

                break;

            case 'Line':

                object = new Line( getGeometry( data.geometry ), getMaterial( data.material ) );

                break;

            case 'LineLoop':

                object = new LineLoop( getGeometry( data.geometry ), getMaterial( data.material ) );

                break;

            case 'LineSegments':

                object = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );

                break;

            case 'PointCloud':
            case 'Points':

                object = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );

                break;

            case 'Sprite':

                object = new Sprite( getMaterial( data.material ) );

                break;

            case 'Group':

                object = new Group();

                break;

            case 'Bone':

                object = new Bone();

                break;

            default:

                object = new Object3D();

        }

        object.uuid = data.uuid;

        if ( data.name !== undefined ) object.name = data.name;

        if ( data.matrix !== undefined ) {

            object.matrix.fromArray( data.matrix );

            if ( data.matrixAutoUpdate !== undefined ) object.matrixAutoUpdate = data.matrixAutoUpdate;
            if ( object.matrixAutoUpdate ) object.matrix.decompose( object.position, object.quaternion, object.scale );

        } else {

            if ( data.position !== undefined ) object.position.fromArray( data.position );
            if ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation );
            if ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion );
            if ( data.scale !== undefined ) object.scale.fromArray( data.scale );

        }

        if ( data.up !== undefined ) object.up.fromArray( data.up );

        if ( data.castShadow !== undefined ) object.castShadow = data.castShadow;
        if ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;

        if ( data.shadow ) {

            if ( data.shadow.intensity !== undefined ) object.shadow.intensity = data.shadow.intensity;
            if ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias;
            if ( data.shadow.normalBias !== undefined ) object.shadow.normalBias = data.shadow.normalBias;
            if ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius;
            if ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize );
            if ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera );

        }

        if ( data.visible !== undefined ) object.visible = data.visible;
        if ( data.frustumCulled !== undefined ) object.frustumCulled = data.frustumCulled;
        if ( data.renderOrder !== undefined ) object.renderOrder = data.renderOrder;
        if ( data.userData !== undefined ) object.userData = data.userData;
        if ( data.layers !== undefined ) object.layers.mask = data.layers;

        if ( data.children !== undefined ) {

            const children = data.children;

            for ( let i = 0; i < children.length; i ++ ) {

                object.add( this.parseObject( children[ i ], geometries, materials, textures, animations ) );

            }

        }

        if ( data.animations !== undefined ) {

            const objectAnimations = data.animations;

            for ( let i = 0; i < objectAnimations.length; i ++ ) {

                const uuid = objectAnimations[ i ];

                object.animations.push( animations[ uuid ] );

            }

        }

        if ( data.type === 'LOD' ) {

            if ( data.autoUpdate !== undefined ) object.autoUpdate = data.autoUpdate;

            const levels = data.levels;

            for ( let l = 0; l < levels.length; l ++ ) {

                const level = levels[ l ];
                const child = object.getObjectByProperty( 'uuid', level.object );

                if ( child !== undefined ) {

                    object.addLevel( child, level.distance, level.hysteresis );

                }

            }

        }

        return object;

    }
bindSkeletons(object: any, skeletons: any): void
Code
bindSkeletons( object, skeletons ) {

        if ( Object.keys( skeletons ).length === 0 ) return;

        object.traverse( function ( child ) {

            if ( child.isSkinnedMesh === true && child.skeleton !== undefined ) {

                const skeleton = skeletons[ child.skeleton ];

                if ( skeleton === undefined ) {

                    console.warn( 'THREE.ObjectLoader: No skeleton found with UUID:', child.skeleton );

                } else {

                    child.bind( skeleton, child.bindMatrix );

                }

            }

        } );

    }
bindLightTargets(object: any): void
Code
bindLightTargets( object ) {

        object.traverse( function ( child ) {

            if ( child.isDirectionalLight || child.isSpotLight ) {

                const uuid = child.target;

                const target = object.getObjectByProperty( 'uuid', uuid );

                if ( target !== undefined ) {

                    child.target = target;

                } else {

                    child.target = new Object3D();

                }

            }

        } );

    }