Selaa lähdekoodia

Fixes SVGLoader arc parsing with zero radius path commands. See #20641

Greg Zanchelli 4 vuotta sitten
vanhempi
commit
0ac84c57b6

+ 26 - 9
examples/jsm/loaders/SVGLoader.js

@@ -282,7 +282,7 @@ SVGLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
 						}
 
 						break;
-
+	
 					case 'L':
 						var numbers = parseFloats( data );
 
@@ -398,15 +398,25 @@ SVGLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
 						var numbers = parseFloats( data );
 
 						for ( var j = 0, jl = numbers.length; j < jl; j += 7 ) {
+							// skip command if start point == end point
+							if( numbers[ j + 5 ] == point.x && numbers[ j + 6 ] == point.y ) continue
 
+							
 							var start = point.clone();
 							point.x = numbers[ j + 5 ];
 							point.y = numbers[ j + 6 ];
 							control.x = point.x;
 							control.y = point.y;
-							parseArcCommand(
-								path, numbers[ j ], numbers[ j + 1 ], numbers[ j + 2 ], numbers[ j + 3 ], numbers[ j + 4 ], start, point
-							);
+
+							if( numbers[ j ] == 0 || numbers[ j + 1 ] == 0 ) {
+								// draw a line if either of the radii == 0
+								path.lineTo( point.x, point.y );
+							}
+							else {
+								parseArcCommand(
+									path, numbers[ j ], numbers[ j + 1 ], numbers[ j + 2 ], numbers[ j + 3 ], numbers[ j + 4 ], start, point
+								);
+							}
 
 							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
 
@@ -585,20 +595,27 @@ SVGLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
 
 					case 'a':
 						var numbers = parseFloats( data );
-
 						for ( var j = 0, jl = numbers.length; j < jl; j += 7 ) {
+							// skip command if start point == end point
+							if( numbers[ j + 5 ] == 0 && numbers[ j + 6 ] == 0 ) continue
 
 							var start = point.clone();
 							point.x += numbers[ j + 5 ];
 							point.y += numbers[ j + 6 ];
 							control.x = point.x;
 							control.y = point.y;
-							parseArcCommand(
-								path, numbers[ j ], numbers[ j + 1 ], numbers[ j + 2 ], numbers[ j + 3 ], numbers[ j + 4 ], start, point
-							);
 
-							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
+							if( numbers[ j ] == 0 || numbers[ j + 1 ] == 0 ) {
+								// draw a line if either of the radii == 0
+								path.lineTo( point.x, point.y );
+							}
+							else {
+								parseArcCommand(
+									path, numbers[ j ], numbers[ j + 1 ], numbers[ j + 2 ], numbers[ j + 3 ], numbers[ j + 4 ], start, point
+								);
+							}
 
+							if ( j === 0 && doSetFirstPoint === true ) firstPoint.copy( point );
 						}
 
 						break;

+ 8 - 0
examples/models/svg/zero-radius.svg

@@ -0,0 +1,8 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="930.29" height="802.11" viewBox="0 0 930.29 802.11">
+  <path
+    d="M731.61,544H889.45A10.5,10.5,0,0,1,900,554.5v16.13a0,0,0,0,1,0,0H713.61a0,0,0,0,1,0,0V562A18,18,0,0,1,731.61,544Z"
+   fill="#40414d" />
+  <path
+    d="M906.69,385.69h8.06a0,0,0,0,1,0,0V563.63a7,7,0,0,1-7,7H901a7,7,0,0,1-7-7V398.35a12.66,12.66,0,0,1,12.66-12.66Z"
+    fill="#40414d" />
+</svg>

+ 2 - 2
examples/webgl_loader_svg.html

@@ -104,8 +104,8 @@
 					"Defs": 'models/svg/tests/testDefs/Svg-defs.svg',
 					"Defs2": 'models/svg/tests/testDefs/Svg-defs2.svg',
 					"Defs3": 'models/svg/tests/testDefs/Wave-defs.svg',
-					"Defs4": 'models/svg/tests/testDefs/defs4.svg'
-
+					"Defs4": 'models/svg/tests/testDefs/defs4.svg',
+					"Zero Radius": 'models/svg/zero-radius.svg'
 
 				} ).name( 'SVG File' ).onChange( update );