浏览代码

Initial support for BFC

Garrett Johnson 6 年之前
父节点
当前提交
a897ea9589
共有 1 个文件被更改,包括 116 次插入15 次删除
  1. 116 15
      examples/js/loaders/LDrawLoader.js

+ 116 - 15
examples/js/loaders/LDrawLoader.js

@@ -271,7 +271,19 @@ THREE.LDrawLoader = ( function () {
 
 			}, onProgress, onError );
 
-			function processObject( text, onProcessed ) {
+			function subobjectLoad( url, onLoad, onProgress, onError, subobject ) {
+
+				var fileLoader = new THREE.FileLoader( scope.manager );
+				fileLoader.setPath( scope.path );
+				fileLoader.load( url, function ( text ) {
+
+					processObject( text, onLoad, subobject );
+
+				}, onProgress, onError );
+
+			}
+
+			function processObject( text, onProcessed, subobject ) {
 
 				var parseScope = scope.newParseScopeLevel();
 				parseScope.url = url;
@@ -284,9 +296,10 @@ THREE.LDrawLoader = ( function () {
 
 					scope.subobjectCache[ currentFileName ] = text;
 
-
 				}
 
+				parseScope.inverted = subobject !== undefined ? subobject.inverted : false;
+
 				// Parse the object (returns a THREE.Group)
 				var objGroup = scope.parse( text );
 
@@ -372,7 +385,7 @@ THREE.LDrawLoader = ( function () {
 					var cached = scope.subobjectCache[ subobject.originalFileName ];
 					if ( cached ) {
 
-						var subobjectGroup = processObject( cached, sync ? undefined : onSubobjectLoaded );
+						var subobjectGroup = processObject( cached, sync ? undefined : onSubobjectLoaded, subobject );
 						if ( sync ) {
 
 							addSubobject( subobject, subobjectGroup );
@@ -462,7 +475,7 @@ THREE.LDrawLoader = ( function () {
 					subobject.url = subobjectURL;
 
 					// Load the subobject
-					scope.load( subobjectURL, onSubobjectLoaded, undefined, onSubobjectError );
+					subobjectLoad( subobjectURL, onSubobjectLoaded, undefined, onSubobjectError, subobject );
 
 				}
 
@@ -587,6 +600,7 @@ THREE.LDrawLoader = ( function () {
 				subobjects: null,
 				numSubobjects: 0,
 				subobjectIndex: 0,
+				inverted: false,
 
 				// Current subobject
 				currentFileName: null,
@@ -897,9 +911,6 @@ THREE.LDrawLoader = ( function () {
 
 			}
 
-			// BFC (Back Face Culling) LDraw language meta extension is not implemented, so set all materials double-sided:
-			material.side = THREE.DoubleSide;
-
 			material.transparent = isTransparent;
 			material.opacity = alpha;
 
@@ -1035,6 +1046,10 @@ THREE.LDrawLoader = ( function () {
 
 			}
 
+			var bfcEnabled = false;
+			var bfcCCW = true;
+			var bfcInverted = false;
+
 			// Parse all line commands
 			for ( lineIndex = 0; lineIndex < numLines; lineIndex ++ ) {
 
@@ -1137,6 +1152,56 @@ THREE.LDrawLoader = ( function () {
 										currentEmbeddedFileName = lp.getRemainingString();
 										currentEmbeddedText = '';
 
+										bfcEnabled = false;
+										bfcCCW = true;
+
+									}
+
+									break;
+
+								case 'BFC':
+
+									while ( ! lp.isAtTheEnd() ) {
+
+										var token = lp.getToken();
+										bfcCCW = true;
+										switch ( token ) {
+
+											case 'CERTIFY':
+											case 'NOCERTIFY':
+
+												bfcEnabled = token === 'CERTIFY';
+
+												break;
+
+											case 'CW':
+											case 'CCW':
+
+												bfcCCW = token === 'CCW';
+
+												break;
+
+											case 'INVERTNEXT':
+
+												bfcInverted = true;
+
+												break;
+
+											case 'CLIP':
+											case 'NOCLIP':
+
+												console.warn( 'THREE.LDrawLoader: BFC CLIP and NOCLIP directives ignored.' );
+
+												break;
+
+											default:
+
+												console.warn( 'THREE.LDrawLoader: BFC directive "' + token + '" is unknown.' );
+
+												break;
+
+										}
+
 									}
 
 									break;
@@ -1205,9 +1270,12 @@ THREE.LDrawLoader = ( function () {
 							originalFileName: fileName,
 							locationState: LDrawLoader.FILE_LOCATION_AS_IS,
 							url: null,
-							triedLowerCase: false
+							triedLowerCase: false,
+							inverted: bfcInverted !== currentParseScope.inverted
 						} );
 
+						bfcInverted = false;
+
 						break;
 
 					// Line type 2: Line segment
@@ -1229,12 +1297,30 @@ THREE.LDrawLoader = ( function () {
 
 						var material = parseColourCode( lp );
 
+						var inverted = currentParseScope.inverted;
+						var ccw = ! bfcEnabled || bfcEnabled && bfcCCW && ! inverted;
+						var v0, v1, v2;
+
+						if ( ccw === true ) {
+
+							v0 = parseVector( lp );
+							v1 = parseVector( lp );
+							v2 = parseVector( lp );
+
+						} else {
+
+							v2 = parseVector( lp );
+							v1 = parseVector( lp );
+							v0 = parseVector( lp );
+
+						}
+
 						triangles.push( {
 							material: material,
 							colourCode: material.userData.code,
-							v0: parseVector( lp ),
-							v1: parseVector( lp ),
-							v2: parseVector( lp )
+							v0: v0,
+							v1: v1,
+							v2: v2
 						} );
 
 						break;
@@ -1244,10 +1330,25 @@ THREE.LDrawLoader = ( function () {
 
 						var material = parseColourCode( lp );
 
-						var v0 = parseVector( lp );
-						var v1 = parseVector( lp );
-						var v2 = parseVector( lp );
-						var v3 = parseVector( lp );
+						var inverted = currentParseScope.inverted;
+						var ccw = ! bfcEnabled || bfcEnabled && bfcCCW && ! inverted;
+						var v0, v1, v2, v3;
+
+						if ( ccw === true ) {
+
+							v0 = parseVector( lp );
+							v1 = parseVector( lp );
+							v2 = parseVector( lp );
+							v3 = parseVector( lp );
+
+						} else {
+
+							v3 = parseVector( lp );
+							v2 = parseVector( lp );
+							v1 = parseVector( lp );
+							v0 = parseVector( lp );
+
+						}
 
 						triangles.push( {
 							material: material,