-
-
Notifications
You must be signed in to change notification settings - Fork 36.1k
SEA3D + Google Draco #14635
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SEA3D + Google Draco #14635
Changes from all commits
d5aa443
a11bba7
d2875e8
1122dbe
14268af
5ff096f
22f2fae
6f337f8
9293089
65b77fc
7867131
5d2e6aa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,212 @@ | ||
| /** | ||
| * 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; | ||
|
|
||
| } | ||
|
|
||
| } ); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,6 +29,8 @@ | |
| <body> | ||
| <div id="info"> | ||
| <a href="http://threejs.org" target="_blank" rel="noopener">Three.JS</a> - Exported by <a href="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/sunag/sea3d" style="color:#FFFFFF" target="_blank" rel="noopener">SEA3D Exporter</a> and edited by <a href="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/sunag/sea3d" style="color:#FFFFFF" target="_blank" rel="noopener">SEA3D Studio</a>. Asset by <a href="http://vhalldez.cgsociety.org/" style="color:#FFFFFF" target="_blank" rel="noopener">Valdez Araujo</a> | ||
| <br/> | ||
| <br/>Geometry Compression with <a href="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/google/draco" style="color:#FFFFFF" target="_blank" rel="noopener">Google Draco</a> and content with LZMA using <a href="http://sunag.github.io/sea3d/IO/index.html" style="color:#FFFFFF" target="_blank">SEA3D I.O.</a> Tools<br> | ||
| </div> | ||
|
|
||
| <script src="../build/three.js"></script> | ||
|
|
@@ -47,6 +49,9 @@ | |
| <script src="js/loaders/sea3d/SEA3DLZMA.js"></script> | ||
| <script src="js/loaders/sea3d/SEA3DLoader.js"></script> | ||
|
|
||
| <script src="js/libs/draco/draco_decoder.js"></script> | ||
| <script src="js/loaders/sea3d/SEA3DDraco.js"></script> | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Both Draco and LZMA on the same asset?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. LZMA is used for content |
||
|
|
||
| <script src="js/Detector.js"></script> | ||
| <script src="js/libs/stats.min.js"></script> | ||
|
|
||
|
|
@@ -73,7 +78,8 @@ | |
| loader = new THREE.SEA3D( { | ||
|
|
||
| autoPlay : true, // Auto play animations | ||
| container : scene // Container to add models | ||
| container : scene, // Container to add models | ||
| progressive : true // Progressive download | ||
|
|
||
| } ); | ||
|
|
||
|
|
@@ -82,17 +88,15 @@ | |
| // Get camera from SEA3D Studio | ||
| // use loader.get... to get others objects | ||
|
|
||
| var cam = loader.getCamera( "Camera007" ); | ||
| camera.position.copy( cam.position ); | ||
| camera.rotation.copy( cam.rotation ); | ||
|
|
||
| controls = new THREE.OrbitControls( camera ); | ||
| //var cam = loader.getCamera( "Camera007" ); | ||
| //camera.position.copy( cam.position ); | ||
| //camera.rotation.copy( cam.rotation ); | ||
|
|
||
| animate(); | ||
| console.log("SEA3D asset loaded!"); | ||
|
|
||
| }; | ||
|
|
||
| loader.load( './models/sea3d/mascot.tjs.sea' ); | ||
| loader.load( './models/sea3d/mascot.draco.tjs.sea' ); | ||
|
|
||
| // | ||
|
|
||
|
|
@@ -105,7 +109,10 @@ | |
| document.body.appendChild( container ); | ||
|
|
||
| camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 ); | ||
| camera.position.set( 1000, - 300, 1000 ); | ||
| camera.position.set( 1000, 1000, 1000 ); | ||
| camera.lookAt( new THREE.Vector3() ); | ||
|
|
||
| controls = new THREE.OrbitControls( camera ); | ||
|
|
||
| renderer = new THREE.WebGLRenderer(); | ||
| renderer.setPixelRatio( window.devicePixelRatio ); | ||
|
|
@@ -180,6 +187,8 @@ | |
|
|
||
| } | ||
|
|
||
| animate(); | ||
|
|
||
| </script> | ||
| </body> | ||
| </html> | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Draco decoder has an
isVersionSupportedmethod that can be used to verify the model was encoded by a version of the library that the current decoder is compatible with — it may be worth storing the Draco version in the asset and checking it here. The Draco library does not guarantee that future versions will be backward compatible (although clearly that is prioritized). The glTF Draco extension is currently locked to a particular version of the Dracolibrarybitstream, to ensure long-term compatibility.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for tip! Really without update the
draco libsthis not work.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@donmccurdy I believe that if update the
draco_decoderany version of draco is compatible until then?Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean, an up-to-date
draco_decoderis compatible with files created by any previous version ofdraco_encoder? I believe that is true today. But it is possible that some future version ofdraco_decodermay not support older files, so recording the encoder version — or just requiring models be created with a particular encoder version — might be safest.See google/draco#79.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(it's totally fine that you're updating the draco libs here though — we have a gltf/ subfolder for the encoder/decoder version required by glTF)
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I test
isVersionSupportedbut this method is out-of-date (I did not understand the reason for this method to be in JS and not in c++ core). The Draco file version is2.2this method returnsfalse, 1.1 for example returnstrue. I belive that this method work with glTF because fixed version of Draco is bellow of 2. I will consider your tip using,try/catchdecoder.DecodeBufferToMesh( buffer, mesh )thanks!https://github.com/google/draco/blob/master/src/draco/javascript/emscripten/version.js
I think that for a reformulate versions of Draco I think of creating a new class, SEA3DDraco2.js or other
classinside this script.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or
decoder.DecodeBufferToMesh( buffer, mesh ), this method too checks compatibility with versions.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, the warning looks good!