/* eslint-disable */
import * as THREE from 'three'
/**
* Author: Pierre Lepers
* Date: 09/12/2013 17:21
*/
var UNCOMPRESSED = 0,
DEFLATE = 1,
LZMA = 2,
AWD_FIELD_INT8 = 1,
AWD_FIELD_INT16 = 2,
AWD_FIELD_INT32 = 3,
AWD_FIELD_UINT8 = 4,
AWD_FIELD_UINT16 = 5,
AWD_FIELD_UINT32 = 6,
AWD_FIELD_FLOAT32 = 7,
AWD_FIELD_FLOAT64 = 8,
AWD_FIELD_BOOL = 21,
AWD_FIELD_COLOR = 22,
AWD_FIELD_BADDR = 23,
AWD_FIELD_STRING = 31,
AWD_FIELD_BYTEARRAY = 32,
AWD_FIELD_VECTOR2x1 = 41,
AWD_FIELD_VECTOR3x1 = 42,
AWD_FIELD_VECTOR4x1 = 43,
AWD_FIELD_MTX3x2 = 44,
AWD_FIELD_MTX3x3 = 45,
AWD_FIELD_MTX4x3 = 46,
AWD_FIELD_MTX4x4 = 47,
BOOL = 21,
COLOR = 22,
BADDR = 23,
INT8 = 1,
INT16 = 2,
INT32 = 3,
UINT8 = 4,
UINT16 = 5,
UINT32 = 6,
FLOAT32 = 7,
FLOAT64 = 8;
var littleEndian = true;
function Block() {
this.id = 0;
this.data = null;
}
function AWDProperties() {}
AWDProperties.prototype = {
set: function( key, value ) {
this[ key ] = value;
},
get: function( key, fallback ) {
if ( this.hasOwnProperty( key ) )
return this[ key ];
else return fallback;
}
};
const AWDLoader = function ( manager ) {
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
this.trunk = new THREE.Object3D();
this.materialFactory = undefined;
this._url = '';
this._baseDir = '';
this._data = undefined;
this._ptr = 0;
this._version = [];
this._streaming = false;
this._optimized_for_accuracy = false;
this._compression = 0;
this._bodylen = 0xFFFFFFFF;
this._blocks = [ new Block() ];
this._accuracyMatrix = false;
this._accuracyGeo = false;
this._accuracyProps = false;
};
AWDLoader.prototype = {
constructor: AWDLoader,
load: function ( url, onLoad, onProgress, onError ) {
var scope = this;
this._url = url;
this._baseDir = url.substr( 0, url.lastIndexOf( '/' ) + 1 );
var loader = new THREE.FileLoader( this.manager );
loader.setResponseType( 'arraybuffer' );
loader.load( url, function ( text ) {
onLoad( scope.parse( text ) );
}, onProgress, onError );
},
parse: function ( data ) {
var blen = data.byteLength;
this._ptr = 0;
this._data = new DataView( data );
this._parseHeader( );
if ( this._compression != 0 ) {
console.error( 'compressed AWD not supported' );
}
if ( ! this._streaming && this._bodylen != data.byteLength - this._ptr ) {
console.error( 'AWDLoader: body len does not match file length', this._bodylen, blen - this._ptr );
}
while ( this._ptr < blen ) {
this.parseNextBlock();
}
return this.trunk;
},
parseNextBlock: function() {
var assetData,
ns, type, len, block,
blockId = this.readU32(),
ns = this.readU8(),
type = this.readU8(),
flags = this.readU8(),
len = this.readU32();
switch ( type ) {
case 1:
assetData = this.parseMeshData( len );
break;
case 22:
assetData = this.parseContainer( len );
break;
case 23:
assetData = this.parseMeshInstance( len );
break;
case 81:
assetData = this.parseMaterial( len );
break;
case 82:
assetData = this.parseTexture( len );
break;
case 101:
assetData = this.parseSkeleton( len );
break;
// case 111:
// assetData = this.parseMeshPoseAnimation(len, true);
// break;
case 112:
assetData = this.parseMeshPoseAnimation( len, false );
break;
case 113:
assetData = this.parseVertexAnimationSet( len );
break;
case 102:
assetData = this.parseSkeletonPose( len );
break;
case 103:
assetData = this.parseSkeletonAnimation( len );
break;
case 122:
assetData = this.parseAnimatorSet( len );
break;
// case 121:
// assetData = parseUVAnimation(len);
// break;
default:
//debug('Ignoring block!',type, len);
this._ptr += len;
break;
}
// Store block reference for later use
this._blocks[ blockId ] = block = new Block();
block.data = assetData;
block.id = blockId;
},
_parseHeader: function () {
var version = this._version,
awdmagic =
( this.readU8() << 16 )
| ( this.readU8() << 8 )
| this.readU8();
if ( awdmagic != 4282180 )
throw new Error( "AWDLoader - bad magic" );
version[ 0 ] = this.readU8();
version[ 1 ] = this.readU8();
var flags = this.readU16();
this._streaming = ( flags & 0x1 ) == 0x1;
if ( ( version[ 0 ] === 2 ) && ( version[ 1 ] === 1 ) ) {
this._accuracyMatrix = ( flags & 0x2 ) === 0x2;
this._accuracyGeo = ( flags & 0x4 ) === 0x4;
this._accuracyProps = ( flags & 0x8 ) === 0x8;
}
this._geoNrType = this._accuracyGeo ? FLOAT64 : FLOAT32;
this._matrixNrType = this._accuracyMatrix ? FLOAT64 : FLOAT32;
this._propsNrType = this._accuracyProps ? FLOAT64 : FLOAT32;
this._optimized_for_accuracy = ( flags & 0x2 ) === 0x2;
this._compression = this.readU8();
this._bodylen = this.readU32();
},
parseContainer: function ( len ) {
var parent,
ctr = new THREE.Object3D(),
par_id = this.readU32(),
mtx = this.parseMatrix4();
ctr.name = this.readUTF();
ctr.applyMatrix( mtx );
parent = this._blocks[ par_id ].data || this.trunk;
parent.add( ctr );
this.parseProperties( {
1: this._matrixNrType,
2: this._matrixNrType,
3: this._matrixNrType,
4: UINT8
} );
ctr.extra = this.parseUserAttributes();
return ctr;
},
parseMeshInstance: function ( len ) {
var name,
mesh, geometries, meshLen, meshes,
par_id, data_id,
mtx,
materials, mat, mat_id,
num_materials,
parent,
i;
par_id = this.readU32();
mtx = this.parseMatrix4();
name = this.readUTF();
data_id = this.readU32();
num_materials = this.readU16();
geometries = this.getBlock( data_id );
materials = [];
for ( i = 0; i < num_materials; i ++ ) {
mat_id = this.readU32();
mat = this.getBlock( mat_id );
materials.push( mat );
}
meshLen = geometries.length;
meshes = [];
// TODO : BufferGeometry don't support "geometryGroups" for now.
// so we create sub meshes for each groups
if ( meshLen > 1 ) {
mesh = new THREE.Object3D();
for ( i = 0; i < meshLen; i ++ ) {
var sm = new THREE.Mesh( geometries[ i ] );
meshes.push( sm );
mesh.add( sm );
}
} else {
mesh = new THREE.Mesh( geometries[ 0 ] );
meshes.push( mesh );
}
mesh.applyMatrix( mtx );
mesh.name = name;
parent = this.getBlock( par_id ) || this.trunk;
parent.add( mesh );
var matLen = materials.length;
var maxLen = Math.max( meshLen, matLen );
for ( i = 0; i < maxLen; i ++ )
meshes[ i % meshLen ].material = materials[ i % matLen ];
// Ignore for now
this.parseProperties( null );
mesh.extra = this.parseUserAttributes();
return mesh;
},
parseMaterial: function ( len ) {
var name,
type,
props,
mat,
attributes,
finalize,
num_methods,
methods_parsed;
name = this.readUTF();
type = this.readU8();
num_methods = this.readU8();
//log( "AWDLoader parseMaterial ",name )
// Read material numerical properties
// (1=color, 2=bitmap url, 11=alpha_blending, 12=alpha_threshold, 13=repeat)
props = this.parseProperties( {
1: AWD_FIELD_INT32,
2: AWD_FIELD_BADDR,
11: AWD_FIELD_BOOL,
12: AWD_FIELD_FLOAT32,
13: AWD_FIELD_BOOL
} );
methods_parsed = 0;
while ( methods_parsed < num_methods ) {
var method_type = this.readU16();
this.parseProperties( null );
this.parseUserAttributes();
}
attributes = this.parseUserAttributes();
if ( this.materialFactory !== undefined ) {
mat = this.materialFactory( name );
if ( mat ) return mat;
}
mat = new THREE.MeshPhongMaterial();
if ( type === 1 ) {
// Color material
mat.color.setHex( props.get( 1, 0xcccccc ) );
} else if ( type === 2 ) {
// Bitmap material
var tex_addr = props.get( 2, 0 );
mat.map = this.getBlock( tex_addr );
}
mat.extra = attributes;
mat.alphaThreshold = props.get( 12, 0.0 );
mat.repeat = props.get( 13, false );
return mat;
},
parseTexture: function( len ) {
var name = this.readUTF(),
type = this.readU8(),
asset,
data_len;
// External
if ( type === 0 ) {
data_len = this.readU32();
var url = this.readUTFBytes( data_len );
console.log( url );
asset = this.loadTexture( url );
} else {
// embed texture not supported
}
// Ignore for now
this.parseProperties( null );
this.parseUserAttributes();
return asset;
},
loadTexture: function( url ) {
var tex = new THREE.Texture();
var loader = new THREE.ImageLoader( this.manager );
loader.load( this._baseDir + url, function( image ) {
tex.image = image;
tex.needsUpdate = true;
} );
return tex;
},
parseSkeleton: function( len ) {
// Array