Skip to content

Commit

Permalink
Merge pull request #19338 from Mugen87/dev49
Browse files Browse the repository at this point in the history
OBJLoader: Better handle inconsistent face definitions.
  • Loading branch information
mrdoob authored May 11, 2020
2 parents 4e6dbb7 + 397c6b1 commit 5db1eb3
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 33 deletions.
87 changes: 71 additions & 16 deletions examples/js/loaders/OBJLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ THREE.OBJLoader = ( function () {
// usemap map_name
var map_use_pattern = /^usemap /;

var vA = new THREE.Vector3();
var vB = new THREE.Vector3();
var vC = new THREE.Vector3();

var ab = new THREE.Vector3();
var cb = new THREE.Vector3();

function ParserState() {

var state = {
Expand Down Expand Up @@ -55,7 +62,9 @@ THREE.OBJLoader = ( function () {
vertices: [],
normals: [],
colors: [],
uvs: []
uvs: [],
hasNormalIndices: false,
hasUVIndices: false
},
materials: [],
smooth: true,
Expand Down Expand Up @@ -248,6 +257,27 @@ THREE.OBJLoader = ( function () {

},

addFaceNormal: function ( a, b, c ) {

var src = this.vertices;
var dst = this.object.geometry.normals;

vA.fromArray( src, a );
vB.fromArray( src, b );
vC.fromArray( src, c );

cb.subVectors( vC, vB );
ab.subVectors( vA, vB );
cb.cross( ab );

cb.normalize();

dst.push( cb.x, cb.y, cb.z );
dst.push( cb.x, cb.y, cb.z );
dst.push( cb.x, cb.y, cb.z );

},

addColor: function ( a, b, c ) {

var src = this.colors;
Expand All @@ -270,6 +300,16 @@ THREE.OBJLoader = ( function () {

},

addDefaultUV: function () {

var dst = this.object.geometry.uvs;

dst.push( 0, 0 );
dst.push( 0, 0 );
dst.push( 0, 0 );

},

addUVLine: function ( a ) {

var src = this.uvs;
Expand All @@ -290,26 +330,45 @@ THREE.OBJLoader = ( function () {
this.addVertex( ia, ib, ic );
this.addColor( ia, ib, ic );

// normals

if ( na !== undefined && na !== '' ) {

var nLen = this.normals.length;

ia = this.parseNormalIndex( na, nLen );
ib = this.parseNormalIndex( nb, nLen );
ic = this.parseNormalIndex( nc, nLen );

this.addNormal( ia, ib, ic );

this.object.geometry.hasNormalIndices = true;

} else {

this.addFaceNormal( ia, ib, ic );

}

// uvs

if ( ua !== undefined && ua !== '' ) {

var uvLen = this.uvs.length;

ia = this.parseUVIndex( ua, uvLen );
ib = this.parseUVIndex( ub, uvLen );
ic = this.parseUVIndex( uc, uvLen );
this.addUV( ia, ib, ic );

}
this.addUV( ia, ib, ic );

if ( na !== undefined && na !== '' ) {
this.object.geometry.hasUVIndices = true;

// Normals are many times the same. If so, skip function call and parseInt.
var nLen = this.normals.length;
ia = this.parseNormalIndex( na, nLen );
} else {

ib = na === nb ? ia : this.parseNormalIndex( nb, nLen );
ic = na === nc ? ia : this.parseNormalIndex( nc, nLen );
// add placeholder values (for inconsistent face definitions)

this.addNormal( ia, ib, ic );
this.addDefaultUV();

}

Expand Down Expand Up @@ -652,14 +711,10 @@ THREE.OBJLoader = ( function () {

buffergeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( geometry.vertices, 3 ) );

if ( geometry.normals.length > 0 ) {
if ( geometry.hasNormalIndices === true ) {

buffergeometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( geometry.normals, 3 ) );

} else {

buffergeometry.computeVertexNormals();

}

if ( geometry.colors.length > 0 ) {
Expand All @@ -669,7 +724,7 @@ THREE.OBJLoader = ( function () {

}

if ( geometry.uvs.length > 0 ) {
if ( geometry.hasUVIndices === true ) {

buffergeometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( geometry.uvs, 2 ) );

Expand Down
90 changes: 73 additions & 17 deletions examples/jsm/loaders/OBJLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import {
Mesh,
MeshPhongMaterial,
Points,
PointsMaterial
PointsMaterial,
Vector3
} from "../../../build/three.module.js";

var OBJLoader = ( function () {
Expand All @@ -28,6 +29,13 @@ var OBJLoader = ( function () {
// usemap map_name
var map_use_pattern = /^usemap /;

var vA = new Vector3();
var vB = new Vector3();
var vC = new Vector3();

var ab = new Vector3();
var cb = new Vector3();

function ParserState() {

var state = {
Expand Down Expand Up @@ -70,7 +78,9 @@ var OBJLoader = ( function () {
vertices: [],
normals: [],
colors: [],
uvs: []
uvs: [],
hasNormalIndices: false,
hasUVIndices: false
},
materials: [],
smooth: true,
Expand Down Expand Up @@ -263,6 +273,27 @@ var OBJLoader = ( function () {

},

addFaceNormal: function ( a, b, c ) {

var src = this.vertices;
var dst = this.object.geometry.normals;

vA.fromArray( src, a );
vB.fromArray( src, b );
vC.fromArray( src, c );

cb.subVectors( vC, vB );
ab.subVectors( vA, vB );
cb.cross( ab );

cb.normalize();

dst.push( cb.x, cb.y, cb.z );
dst.push( cb.x, cb.y, cb.z );
dst.push( cb.x, cb.y, cb.z );

},

addColor: function ( a, b, c ) {

var src = this.colors;
Expand All @@ -285,6 +316,16 @@ var OBJLoader = ( function () {

},

addDefaultUV: function () {

var dst = this.object.geometry.uvs;

dst.push( 0, 0 );
dst.push( 0, 0 );
dst.push( 0, 0 );

},

addUVLine: function ( a ) {

var src = this.uvs;
Expand All @@ -305,26 +346,45 @@ var OBJLoader = ( function () {
this.addVertex( ia, ib, ic );
this.addColor( ia, ib, ic );

// normals

if ( na !== undefined && na !== '' ) {

var nLen = this.normals.length;

ia = this.parseNormalIndex( na, nLen );
ib = this.parseNormalIndex( nb, nLen );
ic = this.parseNormalIndex( nc, nLen );

this.addNormal( ia, ib, ic );

this.object.geometry.hasNormalIndices = true;

} else {

this.addFaceNormal( ia, ib, ic );

}

// uvs

if ( ua !== undefined && ua !== '' ) {

var uvLen = this.uvs.length;

ia = this.parseUVIndex( ua, uvLen );
ib = this.parseUVIndex( ub, uvLen );
ic = this.parseUVIndex( uc, uvLen );
this.addUV( ia, ib, ic );

}
this.addUV( ia, ib, ic );

if ( na !== undefined && na !== '' ) {
this.object.geometry.hasUVIndices = true;

// Normals are many times the same. If so, skip function call and parseInt.
var nLen = this.normals.length;
ia = this.parseNormalIndex( na, nLen );
} else {

ib = na === nb ? ia : this.parseNormalIndex( nb, nLen );
ic = na === nc ? ia : this.parseNormalIndex( nc, nLen );
// add placeholder values (for inconsistent face definitions)

this.addNormal( ia, ib, ic );
this.addDefaultUV();

}

Expand Down Expand Up @@ -667,14 +727,10 @@ var OBJLoader = ( function () {

buffergeometry.setAttribute( 'position', new Float32BufferAttribute( geometry.vertices, 3 ) );

if ( geometry.normals.length > 0 ) {
if ( geometry.hasNormalIndices === true ) {

buffergeometry.setAttribute( 'normal', new Float32BufferAttribute( geometry.normals, 3 ) );

} else {

buffergeometry.computeVertexNormals();

}

if ( geometry.colors.length > 0 ) {
Expand All @@ -684,7 +740,7 @@ var OBJLoader = ( function () {

}

if ( geometry.uvs.length > 0 ) {
if ( geometry.hasUVIndices === true ) {

buffergeometry.setAttribute( 'uv', new Float32BufferAttribute( geometry.uvs, 2 ) );

Expand Down

0 comments on commit 5db1eb3

Please sign in to comment.