julien-c's picture
julien-c HF Staff
do not gitignore the builds
6cd9596
raw
history blame
4.3 kB
/**
* SEA3D - Google Draco
* @author Sunag / http://www.sunag.com.br/
*/
'use strict';
//
// Lossy Compression
//
SEA3D.GeometryDraco = function ( name, data, sea3d ) {
this.name = name;
this.data = data;
this.sea3d = sea3d;
var attrib = data.readUShort(),
i;
this.isBig = ( attrib & 1 ) !== 0;
data.readVInt = this.isBig ? data.readUInt : data.readUShort;
this.groups = [];
if ( attrib & 32 ) {
this.uv = [];
this.uv.length = data.readUByte();
}
if ( attrib & 1024 ) {
var numGroups = data.readUByte(),
groupOffset = 0;
for ( i = 0; i < numGroups; i ++ ) {
var groupLength = data.readVInt() * 3;
this.groups.push( {
start: groupOffset,
count: groupLength,
} );
groupOffset += groupLength;
}
}
var module = SEA3D.GeometryDraco.getModule(),
dracoData = new Int8Array( data.concat( data.position, data.bytesAvailable ).buffer );
var decoder = new module.Decoder();
var buffer = new module.DecoderBuffer();
buffer.Init( dracoData, dracoData.length );
var mesh = new module.Mesh();
var decodingStatus = decoder.DecodeBufferToMesh( buffer, mesh );
if ( ! decodingStatus.ok() ) {
data.position += 5; // jump "DRACO" magic string
var version = data.readUByte() + '.' + data.readUByte(); // draco version
console.error( "SEA3D Draco", version, "decoding failed:", decodingStatus.error_msg(), "You may need update 'draco_decoder.js'." );
// use an empty geometry
this.vertex = new Float32Array();
return;
}
var index = 0;
this.vertex = this.readFloat32Array( module, decoder, mesh, index ++ );
if ( attrib & 4 ) this.normal = this.readFloat32Array( module, decoder, mesh, index ++ );
if ( attrib & 32 ) {
for ( i = 0; i < this.uv.length; i ++ ) {
this.uv[ i ] = this.readFloat32Array( module, decoder, mesh, index ++ );
}
}
if ( attrib & 64 ) {
this.jointPerVertex = decoder.GetAttribute( mesh, index ).num_components();
this.joint = this.readUint16Array( module, decoder, mesh, index ++ );
this.weight = this.readFloat32Array( module, decoder, mesh, index ++ );
}
this.indexes = this.readIndices( module, decoder, mesh );
module.destroy( mesh );
module.destroy( buffer );
module.destroy( decoder );
};
SEA3D.GeometryDraco.getModule = function () {
if ( ! this.module ) {
this.module = DracoDecoderModule();
}
return this.module;
};
SEA3D.GeometryDraco.prototype.type = "sdrc";
SEA3D.GeometryDraco.prototype.readIndices = function ( module, decoder, mesh ) {
var numFaces = mesh.num_faces(),
numIndices = numFaces * 3,
indices = new ( numIndices >= 0xFFFE ? Uint32Array : Uint16Array )( numIndices );
var ia = new module.DracoInt32Array();
for ( var i = 0; i < numFaces; ++ i ) {
decoder.GetFaceFromMesh( mesh, i, ia );
var index = i * 3;
indices[ index ] = ia.GetValue( 0 );
indices[ index + 1 ] = ia.GetValue( 1 );
indices[ index + 2 ] = ia.GetValue( 2 );
}
module.destroy( ia );
return indices;
};
SEA3D.GeometryDraco.prototype.readFloat32Array = function ( module, decoder, mesh, attrib ) {
var attribute = decoder.GetAttribute( mesh, attrib ),
numPoints = mesh.num_points();
var dracoArray = new module.DracoFloat32Array();
decoder.GetAttributeFloatForAllPoints( mesh, attribute, dracoArray );
var size = numPoints * attribute.num_components(),
output = new Float32Array( size );
for ( var i = 0; i < size; ++ i ) {
output[ i ] = dracoArray.GetValue( i );
}
module.destroy( dracoArray );
return output;
};
SEA3D.GeometryDraco.prototype.readUint16Array = function ( module, decoder, mesh, attrib, type ) {
var attribute = decoder.GetAttribute( mesh, attrib ),
numPoints = mesh.num_points();
var dracoArray = new module.DracoUInt16Array();
decoder.GetAttributeUInt16ForAllPoints( mesh, attribute, dracoArray );
var size = numPoints * attribute.num_components(),
output = new Uint16Array( size );
for ( var i = 0; i < size; ++ i ) {
output[ i ] = dracoArray.GetValue( i );
}
module.destroy( dracoArray );
return output;
};
//
// Extension
//
THREE.SEA3D.EXTENSIONS_LOADER.push( {
setTypeRead: function () {
this.file.addClass( SEA3D.GeometryDraco, true );
this.file.typeRead[ SEA3D.GeometryDraco.prototype.type ] = this.readGeometryBuffer;
}
} );