📄 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
ObjectLoader.parseSkeletons(json: any, object: any): {}
¶
Parameters:
json
any
object
any
Returns: {}
Calls:
object.traverse
new Skeleton().fromJSON
Internal Comments:
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
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
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
getGeometry(name: any): any
¶
Parameters:
name
any
Returns: any
Calls:
console.warn
Code
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
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
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
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();
}
}
} );
}