Explorar o código

Fix Blender exports scaling (#826)

Pavel Alexandrov %!s(int64=5) %!d(string=hai) anos
pai
achega
6b63d9a96b
Modificáronse 2 ficheiros con 19 adicións e 9 borrados
  1. 2 2
      hxd/fmt/fbx/BaseLibrary.hx
  2. 17 7
      hxd/fmt/fbx/Parser.hx

+ 2 - 2
hxd/fmt/fbx/BaseLibrary.hx

@@ -248,8 +248,8 @@ class BaseLibrary {
 			case "LastSaved|ApplicationName": app = p.props[4].toString();
 			default:
 			}
-		if( app.indexOf("Blender") >= 0 && unitScale == 1 && originScale == 1 )
-			scaleFactor *= 0.01; // Blender in meters exports FBX to centimeter
+		if( app.indexOf("Blender") >= 0 && unitScale == originScale )
+			scaleFactor = unitScale / 100; // Adjust blender output scaling
 
 		if( scaleFactor == 1 && geometryScaleFactor == 1 )
 			return;

+ 17 - 7
hxd/fmt/fbx/Parser.hx

@@ -182,13 +182,26 @@ class Parser {
 		}
 	}
 	
+	function readBinaryString( length : Int ) : String {
+		if  (length == 0 ) return "";
+		var str = bytes.getString(pos, length);
+		pos += length;
+		// Blender inserts extra data to strings following `\0\1` byte sequence
+		// expecting them to be stripped away due to 0 byte being terminator.
+		final len = str.length;
+		for ( i in 0...len ) {
+			if ( str.charCodeAt(i) == 0 ) {
+				return str.substr(0, i);
+			}
+		}
+		return str;
+	}
+	
 	function parseBinaryNode( nextRecord : Int ) : FbxNode {
 		
 		var numProperties : Int = getVersionedInt32();
 		var propertyListLength : UInt = getVersionedInt32();
-		var nameLen : Int = getByte();
-		var name : String = (nameLen == 0 ? "" : bytes.getString(pos, nameLen));
-		pos += nameLen;
+		var name : String = readBinaryString(getByte());
 		
 		var props : Array<FbxProp> = new Array();
 		var childs : Array<FbxNode> = new Array();
@@ -301,10 +314,7 @@ class Parser {
 				}
 				return PInts(bools);
 			case 'S'.code:
-				var len:Int = getInt32();
-				var s:String = bytes.getString(pos, len);
-				pos += len;
-				return PString(s);
+				return PString(readBinaryString(getInt32()));
 			case 'R'.code:
 				var len:Int = getInt32();
 				var data = Bytes.alloc(len);