Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/manual/en/introduction/Import-via-modules.html
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ <h2>Importable Examples</h2>
<li>exporters
<ul>
<li>ColladaExporter</li>
<li>DRACOExporter</li>
<li>GLTFExporter</li>
<li>MMDExporter</li>
<li>OBJExporter</li>
Expand Down
6 changes: 3 additions & 3 deletions examples/js/exporters/DracoExporter.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
'use strict';

/**
* Export draco compressed files from threejs geometry objects.
*
Expand All @@ -17,6 +15,8 @@
* @author tentone
*/

/* global DracoEncoderModule */

THREE.DRACOExporter = function () {};

THREE.DRACOExporter.prototype = {
Expand Down Expand Up @@ -78,7 +78,7 @@ THREE.DRACOExporter.prototype = {

} else {

var faces = new ( vertices.count > 65535 ? Uint32Array : Uint16Array ) ( vertices.count );
var faces = new ( vertices.count > 65535 ? Uint32Array : Uint16Array )( vertices.count );

for ( var i = 0; i < faces.length; i ++ ) {

Expand Down
20 changes: 20 additions & 0 deletions examples/jsm/exporters/DRACOExporter.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {
BufferGeometry,
Geometry
} from '../../../src/Three';

export interface DRACOExporterOptions {
decodeSpeed?: number;
encodeSpeed?: number;
encoderMethod?: number;
quantization?: number[];
exportUvs?: boolean;
exportNormals?: boolean;
exportColor?: boolean;
}

export class DRACOExporter {
constructor();

parse(geometry: BufferGeometry, options: DRACOExporterOptions): Int8Array;
}
212 changes: 212 additions & 0 deletions examples/jsm/exporters/DRACOExporter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
/**
* Export draco compressed files from threejs geometry objects.
*
* Draco files are compressed and usually are smaller than conventional 3D file formats.
*
* The exporter receives a options object containing
* - decodeSpeed, indicates how to tune the encoder regarding decode speed (0 gives better speed but worst quality)
* - encodeSpeed, indicates how to tune the encoder parameters (0 gives better speed but worst quality)
* - encoderMethod
* - quantization, indicates the presision of each type of data stored in the draco file in the order (POSITION, NORMAL, COLOR, TEX_COORD, GENERIC)
* - exportUvs
* - exportNormals
*
* @class DRACOExporter
* @author tentone
*/

import {
BufferGeometry
} from "../../../build/three.module.js";

/* global DracoEncoderModule */

var DRACOExporter = function () {};

DRACOExporter.prototype = {

constructor: DRACOExporter,

parse: function ( geometry, options ) {


if ( DracoEncoderModule === undefined ) {

throw new Error( 'THREE.DRACOExporter: required the draco_decoder to work.' );

}

if ( options === undefined ) {

options = {

decodeSpeed: 5,
encodeSpeed: 5,
encoderMethod: DRACOExporter.MESH_EDGEBREAKER_ENCODING,
quantization: [ 16, 8, 8, 8, 8 ],
exportUvs: true,
exportNormals: true,
exportColor: false,

};

}

var dracoEncoder = DracoEncoderModule();
var encoder = new dracoEncoder.Encoder();
var builder = new dracoEncoder.MeshBuilder();
var mesh = new dracoEncoder.Mesh();

if ( geometry.isGeometry === true ) {

var bufferGeometry = new BufferGeometry();
bufferGeometry.fromGeometry( geometry );
geometry = bufferGeometry;

}

if ( geometry.isBufferGeometry !== true ) {

throw new Error( 'THREE.DRACOExporter.parse(geometry, options): geometry is not a THREE.Geometry or BufferGeometry instance.' );

}

var vertices = geometry.getAttribute( 'position' );
builder.AddFloatAttributeToMesh( mesh, dracoEncoder.POSITION, vertices.count, vertices.itemSize, vertices.array );

var faces = geometry.getIndex();

if ( faces !== null ) {

builder.AddFacesToMesh( mesh, faces.count, faces.array );

} else {

var faces = new ( vertices.count > 65535 ? Uint32Array : Uint16Array )( vertices.count );

for ( var i = 0; i < faces.length; i ++ ) {

faces[ i ] = i;

}

builder.AddFacesToMesh( mesh, vertices.count, faces );

}

if ( options.exportNormals === true ) {

var normals = geometry.getAttribute( 'normal' );

if ( normals !== undefined ) {

builder.AddFloatAttributeToMesh( mesh, dracoEncoder.NORMAL, normals.count, normals.itemSize, normals.array );

}

}

if ( options.exportUvs === true ) {

var uvs = geometry.getAttribute( 'uv' );

if ( uvs !== undefined ) {

builder.AddFloatAttributeToMesh( mesh, dracoEncoder.TEX_COORD, uvs.count, uvs.itemSize, uvs.array );

}

}

if ( options.exportColor === true ) {

var colors = geometry.getAttribute( 'color' );

if ( colors !== undefined ) {

builder.AddFloatAttributeToMesh( mesh, dracoEncoder.COLOR, colors.count, colors.itemSize, colors.array );

}

}

//Compress using draco encoder

var encodedData = new dracoEncoder.DracoInt8Array();

//Sets the desired encoding and decoding speed for the given options from 0 (slowest speed, but the best compression) to 10 (fastest, but the worst compression).

encoder.SetSpeedOptions( options.encodeSpeed || 5, options.decodeSpeed || 5 );

// Sets the desired encoding method for a given geometry.

if ( options.encoderMethod !== undefined ) {

encoder.SetEncodingMethod( options.encoderMethod );

}

// Sets the quantization (number of bits used to represent) compression options for a named attribute.
// The attribute values will be quantized in a box defined by the maximum extent of the attribute values.
if ( options.quantization !== undefined ) {

for ( var i = 0; i < 5; i ++ ) {

if ( options.quantization[ i ] !== undefined ) {

encoder.SetAttributeQuantization( i, options.quantization[ i ] );

}

}

}

var length = encoder.EncodeMeshToDracoBuffer( mesh, encodedData );
dracoEncoder.destroy( mesh );

if ( length === 0 ) {

throw new Error( 'THREE.DRACOExporter: Draco encoding failed.' );

}

//Copy encoded data to buffer.
var outputData = new Int8Array( new ArrayBuffer( length ) );

for ( var i = 0; i < length; i ++ ) {

outputData[ i ] = encodedData.GetValue( i );

}

dracoEncoder.destroy( encodedData );
dracoEncoder.destroy( encoder );
dracoEncoder.destroy( builder );

return outputData;

}

};

// Encoder methods

DRACOExporter.MESH_EDGEBREAKER_ENCODING = 1;
DRACOExporter.MESH_SEQUENTIAL_ENCODING = 0;

// Geometry type

DRACOExporter.POINT_CLOUD = 0;
DRACOExporter.TRIANGULAR_MESH = 1;

// Attribute type

DRACOExporter.INVALID = - 1;
DRACOExporter.POSITION = 0;
DRACOExporter.NORMAL = 1;
DRACOExporter.COLOR = 2;
DRACOExporter.TEX_COORD = 3;
DRACOExporter.GENERIC = 4;

export { DRACOExporter };
1 change: 1 addition & 0 deletions utils/modularize.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ var files = [
{ path: 'effects/StereoEffect.js', dependencies: [], ignoreList: [] },

{ path: 'exporters/ColladaExporter.js', dependencies: [], ignoreList: [] },
{ path: 'exporters/DRACOExporter.js', dependencies: [], ignoreList: [ 'Geometry' ] },
{ path: 'exporters/GLTFExporter.js', dependencies: [], ignoreList: [ 'AnimationClip', 'Camera', 'Geometry', 'Material', 'Mesh', 'Object3D', 'RGBFormat', 'Scenes', 'ShaderMaterial', 'VertexColors' ] },
{ path: 'exporters/MMDExporter.js', dependencies: [], ignoreList: [] },
{ path: 'exporters/OBJExporter.js', dependencies: [], ignoreList: [] },
Expand Down