Selaa lähdekoodia

OBJLoader: Better handle inconsistent face definitions.

Mugen87 5 vuotta sitten
vanhempi
commit
a1c9b9238a
2 muutettua tiedostoa jossa 128 lisäystä ja 21 poistoa
  1. 63 10
      examples/js/loaders/OBJLoader.js
  2. 65 11
      examples/jsm/loaders/OBJLoader.js

+ 63 - 10
examples/js/loaders/OBJLoader.js

@@ -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 = {
@@ -248,6 +255,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;
@@ -270,6 +298,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;
@@ -290,26 +328,41 @@ 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 );
+
+				}	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 );
 
-				}
-
-				if ( na !== undefined && na !== '' ) {
+					this.addUV( ia, ib, ic );
 
-					// 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();
 
 				}
 

+ 65 - 11
examples/jsm/loaders/OBJLoader.js

@@ -14,7 +14,8 @@ import {
 	Mesh,
 	MeshPhongMaterial,
 	Points,
-	PointsMaterial
+	PointsMaterial,
+	Vector3
 } from "../../../build/three.module.js";
 
 var OBJLoader = ( function () {
@@ -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 = {
@@ -263,6 +271,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;
@@ -285,6 +314,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;
@@ -305,26 +344,41 @@ 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 );
+
+				}	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 );
 
-				}
-
-				if ( na !== undefined && na !== '' ) {
+					this.addUV( ia, ib, ic );
 
-					// 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();
 
 				}