Skip to content

Commit

Permalink
Merge pull request #20706 from Mugen87/dev43
Browse files Browse the repository at this point in the history
DRACOExporter: Properly support point clouds.
  • Loading branch information
mrdoob committed Nov 20, 2020
2 parents d503f14 + 7cdeceb commit 4356a12
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 68 deletions.
116 changes: 84 additions & 32 deletions examples/js/exporters/DRACOExporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,13 @@ THREE.DRACOExporter.prototype = {

constructor: THREE.DRACOExporter,

parse: function ( geometry, options ) {
parse: function ( object, options ) {

if ( object.isBufferGeometry === true || object.isGeometry === true ) {

throw new Error( 'DRACOExporter: The first parameter of parse() is now an instance of Mesh or Points.' );

}

if ( DracoEncoderModule === undefined ) {

Expand All @@ -45,15 +50,17 @@ THREE.DRACOExporter.prototype = {

}

var geometry = object.geometry;

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

if ( geometry.isGeometry === true ) {

var bufferGeometry = new THREE.BufferGeometry();
bufferGeometry.fromGeometry( geometry );
bufferGeometry.setFromObject( object );
geometry = bufferGeometry;

}
Expand All @@ -64,63 +71,94 @@ THREE.DRACOExporter.prototype = {

}

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

var faces = geometry.getIndex();
builder = new dracoEncoder.MeshBuilder();
dracoObject = new dracoEncoder.Mesh();

if ( faces !== null ) {
var vertices = geometry.getAttribute( 'position' );
builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.POSITION, vertices.count, vertices.itemSize, vertices.array );

builder.AddFacesToMesh( mesh, faces.count / 3, faces.array );
var faces = geometry.getIndex();

} else {
if ( faces !== null ) {

var faces = new ( vertices.count > 65535 ? Uint32Array : Uint16Array )( vertices.count );
builder.AddFacesToMesh( dracoObject, faces.count / 3, faces.array );

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

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

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

faces[ i ] = i;

}

faces[ i ] = i;
builder.AddFacesToMesh( dracoObject, vertices.count, faces );

}

builder.AddFacesToMesh( mesh, vertices.count, faces );
if ( options.exportNormals === true ) {

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

if ( normals !== undefined ) {

if ( options.exportNormals === true ) {
builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.NORMAL, normals.count, normals.itemSize, normals.array );

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

}

if ( normals !== undefined ) {
if ( options.exportUvs === true ) {

builder.AddFloatAttributeToMesh( mesh, dracoEncoder.NORMAL, normals.count, normals.itemSize, normals.array );
var uvs = geometry.getAttribute( 'uv' );

if ( uvs !== undefined ) {

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

}

}

}
if ( options.exportColor === true ) {

if ( options.exportUvs === true ) {
var colors = geometry.getAttribute( 'color' );

var uvs = geometry.getAttribute( 'uv' );
if ( colors !== undefined ) {

if ( uvs !== undefined ) {
builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.COLOR, colors.count, colors.itemSize, colors.array );

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

}

}
} else if ( object.isPoints === true ) {

builder = new dracoEncoder.PointCloudBuilder();
dracoObject = new dracoEncoder.PointCloud();

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

if ( options.exportColor === true ) {
if ( options.exportColor === true ) {

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

if ( colors !== undefined ) {
if ( colors !== undefined ) {

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

}

}

} else {

throw new Error( 'DRACOExporter: Unsupported object type.' );

}

//Compress using draco encoder
Expand All @@ -129,7 +167,10 @@ THREE.DRACOExporter.prototype = {

//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 );
var encodeSpeed = ( options.encodeSpeed !== undefined ) ? options.encodeSpeed : 5;
var decodeSpeed = ( options.decodeSpeed !== undefined ) ? options.decodeSpeed : 5;

encoder.SetSpeedOptions( encodeSpeed, decodeSpeed );

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

Expand All @@ -155,8 +196,19 @@ THREE.DRACOExporter.prototype = {

}

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

if ( object.isMesh === true ) {

length = encoder.EncodeMeshToDracoBuffer( dracoObject, encodedData );

} else {

length = encoder.EncodePointCloudToDracoBuffer( dracoObject, true, encodedData );

}

dracoEncoder.destroy( dracoObject );

if ( length === 0 ) {

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

export interface DRACOExporterOptions {
Expand All @@ -17,6 +17,6 @@ export class DRACOExporter {

constructor();

parse( geometry: BufferGeometry | Geometry, options: DRACOExporterOptions ): Int8Array;
parse( object: Mesh | Points, options: DRACOExporterOptions ): Int8Array;

}
116 changes: 84 additions & 32 deletions examples/jsm/exporters/DRACOExporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@ DRACOExporter.prototype = {

constructor: DRACOExporter,

parse: function ( geometry, options ) {
parse: function ( object, options ) {

if ( object.isBufferGeometry === true || object.isGeometry === true ) {

throw new Error( 'DRACOExporter: The first parameter of parse() is now an instance of Mesh or Points.' );

}

if ( DracoEncoderModule === undefined ) {

Expand All @@ -49,15 +54,17 @@ DRACOExporter.prototype = {

}

var geometry = object.geometry;

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

if ( geometry.isGeometry === true ) {

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

}
Expand All @@ -68,63 +75,94 @@ DRACOExporter.prototype = {

}

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

var faces = geometry.getIndex();
builder = new dracoEncoder.MeshBuilder();
dracoObject = new dracoEncoder.Mesh();

if ( faces !== null ) {
var vertices = geometry.getAttribute( 'position' );
builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.POSITION, vertices.count, vertices.itemSize, vertices.array );

builder.AddFacesToMesh( mesh, faces.count / 3, faces.array );
var faces = geometry.getIndex();

} else {
if ( faces !== null ) {

var faces = new ( vertices.count > 65535 ? Uint32Array : Uint16Array )( vertices.count );
builder.AddFacesToMesh( dracoObject, faces.count / 3, faces.array );

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

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

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

faces[ i ] = i;

}

faces[ i ] = i;
builder.AddFacesToMesh( dracoObject, vertices.count, faces );

}

builder.AddFacesToMesh( mesh, vertices.count, faces );
if ( options.exportNormals === true ) {

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

if ( normals !== undefined ) {

if ( options.exportNormals === true ) {
builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.NORMAL, normals.count, normals.itemSize, normals.array );

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

}

if ( normals !== undefined ) {
if ( options.exportUvs === true ) {

builder.AddFloatAttributeToMesh( mesh, dracoEncoder.NORMAL, normals.count, normals.itemSize, normals.array );
var uvs = geometry.getAttribute( 'uv' );

if ( uvs !== undefined ) {

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

}

}

}
if ( options.exportColor === true ) {

if ( options.exportUvs === true ) {
var colors = geometry.getAttribute( 'color' );

var uvs = geometry.getAttribute( 'uv' );
if ( colors !== undefined ) {

if ( uvs !== undefined ) {
builder.AddFloatAttributeToMesh( dracoObject, dracoEncoder.COLOR, colors.count, colors.itemSize, colors.array );

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

}

}
} else if ( object.isPoints === true ) {

builder = new dracoEncoder.PointCloudBuilder();
dracoObject = new dracoEncoder.PointCloud();

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

if ( options.exportColor === true ) {
if ( options.exportColor === true ) {

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

if ( colors !== undefined ) {
if ( colors !== undefined ) {

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

}

}

} else {

throw new Error( 'DRACOExporter: Unsupported object type.' );

}

//Compress using draco encoder
Expand All @@ -133,7 +171,10 @@ DRACOExporter.prototype = {

//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 );
var encodeSpeed = ( options.encodeSpeed !== undefined ) ? options.encodeSpeed : 5;
var decodeSpeed = ( options.decodeSpeed !== undefined ) ? options.decodeSpeed : 5;

encoder.SetSpeedOptions( encodeSpeed, decodeSpeed );

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

Expand All @@ -159,8 +200,19 @@ DRACOExporter.prototype = {

}

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

if ( object.isMesh === true ) {

length = encoder.EncodeMeshToDracoBuffer( dracoObject, encodedData );

} else {

length = encoder.EncodePointCloudToDracoBuffer( dracoObject, true, encodedData );

}

dracoEncoder.destroy( dracoObject );

if ( length === 0 ) {

Expand Down
Loading

0 comments on commit 4356a12

Please sign in to comment.