Spaces:
Running
Running
| /** | |
| * SEA3D - Google Draco | |
| * @author Sunag / http://www.sunag.com.br/ | |
| */ | |
| ; | |
| // | |
| // 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; | |
| } | |
| } ); | |