Skip to content

Commit

Permalink
Merge pull request #12896 from kaisalmen/OBJLoader2_V221
Browse files Browse the repository at this point in the history
OBJLoader V2.2.1
  • Loading branch information
mrdoob authored Dec 18, 2017
2 parents b50726a + cb2280f commit e025c48
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 127 deletions.
14 changes: 11 additions & 3 deletions examples/js/loaders/LoaderSupport.js
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ THREE.LoaderSupport.ResourceDescriptor = (function () {
if ( urlParts.length < 2 ) {

this.path = null;
this.name = this.name = url;
this.name = url;
this.url = url;

} else {
Expand Down Expand Up @@ -989,7 +989,7 @@ THREE.LoaderSupport.WorkerRunnerRefImpl = (function () {
*/
THREE.LoaderSupport.WorkerSupport = (function () {

var WORKER_SUPPORT_VERSION = '2.0.0';
var WORKER_SUPPORT_VERSION = '2.0.1';

var Validator = THREE.LoaderSupport.Validator;

Expand Down Expand Up @@ -1110,7 +1110,15 @@ THREE.LoaderSupport.WorkerSupport = (function () {
LoaderWorker.prototype._postMessage = function () {
if ( Validator.isValid( this.queuedMessage ) && Validator.isValid( this.worker ) ) {

this.worker.postMessage( this.queuedMessage );
if ( this.queuedMessage.data.input instanceof ArrayBuffer ) {

this.worker.postMessage( this.queuedMessage, [ this.queuedMessage.data.input ] );

} else {

this.worker.postMessage( this.queuedMessage );

}

}
};
Expand Down
182 changes: 65 additions & 117 deletions examples/js/loaders/OBJLoader2.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ if ( THREE.LoaderSupport === undefined ) console.error( '"THREE.LoaderSupport" i
*/
THREE.OBJLoader2 = (function () {

var OBJLOADER2_VERSION = '2.2.0';
var OBJLOADER2_VERSION = '2.2.1';
var LoaderBase = THREE.LoaderSupport.LoaderBase;
var Validator = THREE.LoaderSupport.Validator;
var ConsoleLogger = THREE.LoaderSupport.ConsoleLogger;
Expand Down Expand Up @@ -297,8 +297,7 @@ THREE.OBJLoader2 = (function () {
input: content,
options: null
}
},
[ content.buffer ]
}
);
};

Expand Down Expand Up @@ -354,7 +353,6 @@ THREE.OBJLoader2 = (function () {
};
this.logger = new ConsoleLogger();
this.totalBytes = 0;
this.reachedFaces = false;
};

Parser.prototype.setUseAsync = function ( useAsync ) {
Expand Down Expand Up @@ -560,28 +558,7 @@ THREE.OBJLoader2 = (function () {

switch ( buffer[ 0 ] ) {
case Consts.LINE_V:
// object complete instance required if reached faces already (= reached next block of v)
if ( this.reachedFaces ) {

if ( this.rawMesh.colors.length > 0 && this.rawMesh.colors.length !== this.rawMesh.vertices.length ) {

throw 'Vertex Colors were detected, but vertex count and color count do not match!';

}
// only when new vertices after faces are detected complete new mesh is prepared (reset offsets, etc)
this.processCompletedMesh( this.rawMesh.objectName, this.rawMesh.groupName, currentByte, true );
this.reachedFaces = false;

}
if ( bufferPointer === 4 ) {

this.rawMesh.pushVertex( buffer )

} else {

this.rawMesh.pushVertexAndVertextColors( buffer );

}
this.rawMesh.pushVertex( buffer, bufferPointer > 4 );
break;

case Consts.LINE_VT:
Expand All @@ -593,7 +570,6 @@ THREE.OBJLoader2 = (function () {
break;

case Consts.LINE_F:
this.reachedFaces = true;
this.rawMesh.processFaces( buffer, bufferPointer, countSlashes( slashSpacePattern, slashSpacePatternPointer ) );
break;

Expand All @@ -607,12 +583,15 @@ THREE.OBJLoader2 = (function () {
break;

case Consts.LINE_G:
this.processCompletedMesh( this.rawMesh.objectName, concatStringBuffer( buffer, bufferPointer, slashSpacePattern ), currentByte, false );
// 'g' leads to creation of mesh if valid data (faces declaration was done before), otherwise only groupName gets set
this.processCompletedMesh( currentByte );
this.rawMesh.pushGroup( concatStringBuffer( buffer, bufferPointer, slashSpacePattern ) );
flushStringBuffer( buffer, bufferPointer );
break;

case Consts.LINE_O:
this.processCompletedMesh( concatStringBuffer( buffer, bufferPointer, slashSpacePattern ), this.rawMesh.groupName, currentByte, false );
// 'o' is pure meta-information and does not result in creation of new meshes
this.rawMesh.pushObject( concatStringBuffer( buffer, bufferPointer, slashSpacePattern ) );
flushStringBuffer( buffer, bufferPointer );
break;

Expand Down Expand Up @@ -645,43 +624,40 @@ THREE.OBJLoader2 = (function () {
'\n\tReal RawMeshSubGroup count: ' + report.subGroups;
};

Parser.prototype.processCompletedMesh = function ( objectName, groupName, currentByte, beginNewObject ) {
Parser.prototype.processCompletedMesh = function ( currentByte ) {
var result = this.rawMesh.finalize();
if ( Validator.isValid( result ) ) {

this.inputObjectCount++;
if ( this.rawMesh.colors.length > 0 && this.rawMesh.colors.length !== this.rawMesh.vertices.length ) {

throw 'Vertex Colors were detected, but vertex count and color count do not match!';

}
if ( this.logger.isDebug() ) this.logger.logDebug( this.createRawMeshReport( this.rawMesh, this.inputObjectCount ) );
this.inputObjectCount++;

this.buildMesh( result, currentByte );
var progressBytesPercent = currentByte / this.totalBytes;
this.callbackProgress( 'Completed [o: ' + this.rawMesh.objectName + ' g:' + this.rawMesh.groupName + '] Total progress: ' + ( progressBytesPercent * 100 ).toFixed( 2 ) + '%', progressBytesPercent );
this.rawMesh = beginNewObject ? this.rawMesh.newInstanceResetOffsets() : this.rawMesh.newInstanceKeepOffsets();
this.rawMesh.reset( this.rawMesh.smoothingGroup.splitMaterials );

return true;

} else {

return false;
}
// Always update group an object name in case they have changed and are valid
if ( this.rawMesh.objectName !== objectName && Validator.isValid( objectName ) ) this.rawMesh.pushObject( objectName );
if ( this.rawMesh.groupName !== groupName && Validator.isValid( groupName ) ) this.rawMesh.pushGroup( groupName );
};

Parser.prototype.finalize = function ( currentByte ) {
this.logger.logInfo( 'Global output object count: ' + this.outputObjectCount );
var result = Validator.isValid( this.rawMesh ) ? this.rawMesh.finalize() : null;
if ( Validator.isValid( result ) ) {

this.inputObjectCount++;
if ( this.logger.isDebug() ) this.logger.logDebug( this.createRawMeshReport( this.rawMesh, this.inputObjectCount ) );
this.buildMesh( result, currentByte );

if ( this.logger.isEnabled() ) {

var parserFinalReport = 'Overall counts: ' +
'\n\tVertices: ' + this.counts.vertices +
'\n\tFaces: ' + this.counts.faces +
'\n\tMultiple definitions: ' + this.counts.doubleIndicesCount;
this.logger.logInfo( parserFinalReport );
if ( this.processCompletedMesh( currentByte ) && this.logger.isEnabled() ) {

}
var progressBytesPercent = currentByte / this.totalBytes;
this.callbackProgress( 'Completed Parsing: 100.00%', progressBytesPercent );
var parserFinalReport = 'Overall counts: ' +
'\n\tVertices: ' + this.counts.vertices +
'\n\tFaces: ' + this.counts.faces +
'\n\tMultiple definitions: ' + this.counts.doubleIndicesCount;
this.logger.logInfo( parserFinalReport );

}
};
Expand Down Expand Up @@ -836,11 +812,11 @@ THREE.OBJLoader2 = (function () {
if ( this.logger.isDebug() ) {
var materialIndexLine = Validator.isValid( selectedMaterialIndex ) ? '\n\t\tmaterialIndex: ' + selectedMaterialIndex : '';
var createdReport = 'Output Object no.: ' + this.outputObjectCount +
'\n\t\tobjectName: ' + rawObjectDescription.objectName +
'\n\t\tgroupName: ' + rawObjectDescription.groupName +
'\n\t\tmaterialName: ' + rawObjectDescription.materialName +
materialIndexLine +
'\n\t\tmaterialName: ' + rawObjectDescription.materialName +
'\n\t\tsmoothingGroup: ' + rawObjectDescription.smoothingGroup +
'\n\t\tobjectName: ' + rawObjectDescription.objectName +
'\n\t\t#vertices: ' + rawObjectDescription.vertices.length / 3 +
'\n\t\t#indices: ' + rawObjectDescription.indices.length +
'\n\t\t#colors: ' + rawObjectDescription.colors.length / 3 +
Expand Down Expand Up @@ -892,82 +868,51 @@ THREE.OBJLoader2 = (function () {
*/
var RawMesh = (function () {

function RawMesh( materialPerSmoothingGroup, useIndices, disregardNormals, activeMtlName ) {
this.globalVertexOffset = 1;
this.globalUvOffset = 1;
this.globalNormalOffset = 1;

function RawMesh( materialPerSmoothingGroup, useIndices, disregardNormals ) {
this.vertices = [];
this.colors = [];
this.normals = [];
this.uvs = [];

// faces are stored according combined index of group, material and smoothingGroup (0 or not)
this.activeMtlName = Validator.verifyInput( activeMtlName, '' );
this.useIndices = useIndices === true;
this.disregardNormals = disregardNormals === true;

this.objectName = '';
this.groupName = '';
this.activeMtlName = '';
this.mtllibName = '';
this.reset( materialPerSmoothingGroup );
}

RawMesh.prototype.reset = function ( materialPerSmoothingGroup ) {
// faces are stored according combined index of group, material and smoothingGroup (0 or not)
this.subGroups = [];
this.subGroupInUse = null;
this.smoothingGroup = {
splitMaterials: materialPerSmoothingGroup === true,
normalized: -1,
real: -1
};
this.useIndices = useIndices === true;
this.disregardNormals = disregardNormals === true;

this.mtlCount = 0;
this.smoothingGroupCount = 0;

this.subGroups = [];
this.subGroupInUse = null;
// this default index is required as it is possible to define faces without 'g' or 'usemtl'
this.pushSmoothingGroup( 1 );

this.doubleIndicesCount = 0;
this.faceCount = 0;
}

RawMesh.prototype.newInstanceResetOffsets = function () {
var newRawObject = new RawMesh( this.smoothingGroup.splitMaterials, this.useIndices, this.disregardNormals, this.activeMtlName );

// move indices forward
newRawObject.globalVertexOffset = this.globalVertexOffset + this.vertices.length / 3;
newRawObject.globalUvOffset = this.globalUvOffset + this.uvs.length / 2;
newRawObject.globalNormalOffset = this.globalNormalOffset + this.normals.length / 3;

return newRawObject;
};

RawMesh.prototype.newInstanceKeepOffsets = function () {
var newRawObject = new RawMesh( this.smoothingGroup.splitMaterials, this.useIndices, this.disregardNormals, this.activeMtlName );
// keep objectName
newRawObject.pushObject( this.objectName );

// keep current buffers and indices forward
newRawObject.vertices = this.vertices;
newRawObject.colors = this.colors;
newRawObject.uvs = this.uvs;
newRawObject.normals = this.normals;
newRawObject.globalVertexOffset = this.globalVertexOffset;
newRawObject.globalUvOffset = this.globalUvOffset;
newRawObject.globalNormalOffset = this.globalNormalOffset;

return newRawObject;
this.mtlCount = 0;
this.smoothingGroupCount = 0;
};

RawMesh.prototype.pushVertex = function ( buffer ) {
RawMesh.prototype.pushVertex = function ( buffer, haveVertexColors ) {
this.vertices.push( parseFloat( buffer[ 1 ] ) );
this.vertices.push( parseFloat( buffer[ 2 ] ) );
this.vertices.push( parseFloat( buffer[ 3 ] ) );
};
if ( haveVertexColors ) {

RawMesh.prototype.pushVertexAndVertextColors = function ( buffer ) {
this.vertices.push( parseFloat( buffer[ 1 ] ) );
this.vertices.push( parseFloat( buffer[ 2 ] ) );
this.vertices.push( parseFloat( buffer[ 3 ] ) );
this.colors.push( parseFloat( buffer[ 4 ] ) );
this.colors.push( parseFloat( buffer[ 5 ] ) );
this.colors.push( parseFloat( buffer[ 6 ] ) );
this.colors.push( parseFloat( buffer[ 4 ] ) );
this.colors.push( parseFloat( buffer[ 5 ] ) );
this.colors.push( parseFloat( buffer[ 6 ] ) );

}
};

RawMesh.prototype.pushUv = function ( buffer ) {
Expand All @@ -981,6 +926,10 @@ THREE.OBJLoader2 = (function () {
this.normals.push( parseFloat( buffer[ 3 ] ) );
};

RawMesh.prototype.pushGroup = function ( groupName ) {
this.groupName = Validator.verifyInput( groupName, '' );
};

RawMesh.prototype.pushObject = function ( objectName ) {
this.objectName = Validator.verifyInput( objectName, '' );
};
Expand All @@ -989,10 +938,6 @@ THREE.OBJLoader2 = (function () {
this.mtllibName = Validator.verifyInput( mtllibName, '' );
};

RawMesh.prototype.pushGroup = function ( groupName ) {
this.groupName = Validator.verifyInput( groupName, '' );
};

RawMesh.prototype.pushUsemtl = function ( mtlName ) {
if ( this.activeMtlName === mtlName || ! Validator.isValid( mtlName ) ) return;
this.activeMtlName = mtlName;
Expand Down Expand Up @@ -1037,7 +982,7 @@ THREE.OBJLoader2 = (function () {
// "f vertex ..."
if ( slashesCount === 0 ) {

for ( i = 2, length = bufferLength - 1; i < length; i ++ ) {
for ( i = 2, length = bufferLength; i < length; i ++ ) {

this.buildFace( buffer[ 1 ] );
this.buildFace( buffer[ i ] );
Expand Down Expand Up @@ -1081,20 +1026,22 @@ THREE.OBJLoader2 = (function () {
}
};


RawMesh.prototype.buildFace = function ( faceIndexV, faceIndexU, faceIndexN ) {
var sgiu = this.subGroupInUse;
if ( this.disregardNormals ) faceIndexN = undefined;
var scope = this;
var updateRawObjectDescriptionInUse = function () {

var indexPointerV = ( parseInt( faceIndexV ) - scope.globalVertexOffset ) * 3;
var indexPointerC = scope.colors.length > 0 ? indexPointerV : null;
var faceIndexVi = parseInt( faceIndexV );
var indexPointerV = 3 * ( faceIndexVi > 0 ? faceIndexVi - 1 : faceIndexVi + scope.vertices.length / 3 );

var vertices = sgiu.vertices;
vertices.push( scope.vertices[ indexPointerV++ ] );
vertices.push( scope.vertices[ indexPointerV++ ] );
vertices.push( scope.vertices[ indexPointerV ] );

var indexPointerC = scope.colors.length > 0 ? indexPointerV : null;
if ( indexPointerC !== null ) {

var colors = sgiu.colors;
Expand All @@ -1106,15 +1053,17 @@ THREE.OBJLoader2 = (function () {

if ( faceIndexU ) {

var indexPointerU = ( parseInt( faceIndexU ) - scope.globalUvOffset ) * 2;
var faceIndexUi = parseInt( faceIndexU );
var indexPointerU = 2 * ( faceIndexUi > 0 ? faceIndexUi - 1 : faceIndexUi + scope.uvs.length / 2 );
var uvs = sgiu.uvs;
uvs.push( scope.uvs[ indexPointerU++ ] );
uvs.push( scope.uvs[ indexPointerU ] );

}
if ( faceIndexN ) {

var indexPointerN = ( parseInt( faceIndexN ) - scope.globalNormalOffset ) * 3;
var faceIndexNi = parseInt( faceIndexN );
var indexPointerN = 3 * ( faceIndexNi > 0 ? faceIndexNi - 1 : faceIndexNi + scope.normals.length / 3 );
var normals = sgiu.normals;
normals.push( scope.normals[ indexPointerN++ ] );
normals.push( scope.normals[ indexPointerN++ ] );
Expand Down Expand Up @@ -1348,12 +1297,11 @@ THREE.OBJLoader2 = (function () {
* @memberOf THREE.OBJLoader2
*
* @param {string} url URL to the file
* @param {string} name The name of the object
* @param {Object} content The file content as arraybuffer or text
* @param {function} callbackOnLoad
* @param {string} [crossOrigin] CORS value
*/
OBJLoader2.prototype.loadMtl = function ( url, name, content, callbackOnLoad, crossOrigin ) {
OBJLoader2.prototype.loadMtl = function ( url, content, callbackOnLoad, crossOrigin ) {
var resource = new THREE.LoaderSupport.ResourceDescriptor( url, 'MTL' );
resource.setContent( content );
this._loadMtl( resource, callbackOnLoad, crossOrigin );
Expand Down
Loading

0 comments on commit e025c48

Please sign in to comment.