FBX: fix build error due to rename

experimental
Kirill Vainer 10 years ago
parent 0a5b68983e
commit 6f29772862
  1. 75
      jme3-plugins/src/fbx/java/com/jme3/scene/plugins/fbx/file/FbxDump.java
  2. 70
      jme3-plugins/src/fbx/java/com/jme3/scene/plugins/fbx/file/FbxElement.java
  3. 8
      jme3-plugins/src/fbx/java/com/jme3/scene/plugins/fbx/file/FbxFile.java
  4. 16
      jme3-plugins/src/fbx/java/com/jme3/scene/plugins/fbx/file/FbxReader.java

@ -37,6 +37,8 @@ import java.lang.reflect.Array;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
/** /**
* Quick n' dirty dumper of FBX binary files. * Quick n' dirty dumper of FBX binary files.
@ -45,12 +47,14 @@ import java.util.Map;
* *
* @author Kirill Vainer * @author Kirill Vainer
*/ */
public final class FBXDump { public final class FbxDump {
private static final Logger logger = Logger.getLogger(FbxDump.class.getName());
private static final DecimalFormat DECIMAL_FORMAT private static final DecimalFormat DECIMAL_FORMAT
= new DecimalFormat("0.0000000000"); = new DecimalFormat("0.0000000000");
private FBXDump() { } private FbxDump() { }
/** /**
* Creates a map between object UIDs and the objects themselves. * Creates a map between object UIDs and the objects themselves.
@ -58,16 +62,17 @@ public final class FBXDump {
* @param file The file to create the mappings for. * @param file The file to create the mappings for.
* @return The UID to object map. * @return The UID to object map.
*/ */
private static Map<Long, FBXElement> createUidToObjectMap(FBXFile file) { private static Map<FbxId, FbxElement> createUidToObjectMap(FbxFile file) {
Map<Long, FBXElement> uidToObjectMap = new HashMap<Long, FBXElement>(); Map<FbxId, FbxElement> uidToObjectMap = new HashMap<FbxId, FbxElement>();
for (FBXElement rootElement : file.rootElements) { for (FbxElement rootElement : file.rootElements) {
if (rootElement.id.equals("Objects")) { if (rootElement.id.equals("Objects")) {
for (FBXElement fbxObj : rootElement.children) { for (FbxElement fbxObj : rootElement.children) {
if (fbxObj.propertiesTypes[0] != 'L') { FbxId uid = FbxId.getObjectId(fbxObj);
continue; // error if (uid != null) {
}
Long uid = (Long) fbxObj.properties.get(0);
uidToObjectMap.put(uid, fbxObj); uidToObjectMap.put(uid, fbxObj);
} else {
logger.log(Level.WARNING, "Cannot determine ID for object: {0}", fbxObj);
}
} }
} }
} }
@ -79,8 +84,8 @@ public final class FBXDump {
* *
* @param file the file to dump. * @param file the file to dump.
*/ */
public static void dumpFBX(FBXFile file) { public static void dumpFile(FbxFile file) {
dumpFBX(file, System.out); dumpFile(file, System.out);
} }
/** /**
@ -89,11 +94,11 @@ public final class FBXDump {
* @param file the file to dump. * @param file the file to dump.
* @param out the output stream where to output. * @param out the output stream where to output.
*/ */
public static void dumpFBX(FBXFile file, OutputStream out) { public static void dumpFile(FbxFile file, OutputStream out) {
Map<Long, FBXElement> uidToObjectMap = createUidToObjectMap(file); Map<FbxId, FbxElement> uidToObjectMap = createUidToObjectMap(file);
PrintStream ps = new PrintStream(out); PrintStream ps = new PrintStream(out);
for (FBXElement rootElement : file.rootElements) { for (FbxElement rootElement : file.rootElements) {
dumpFBXElement(rootElement, ps, 0, uidToObjectMap); dumpElement(rootElement, ps, 0, uidToObjectMap);
} }
} }
@ -112,9 +117,9 @@ public final class FBXDump {
return string.replaceAll("\u0000\u0001", "::"); return string.replaceAll("\u0000\u0001", "::");
} }
protected static void dumpFBXProperty(String id, char propertyType, protected static void dumpProperty(String id, char propertyType,
Object property, PrintStream ps, Object property, PrintStream ps,
Map<Long, FBXElement> uidToObjectMap) { Map<FbxId, FbxElement> uidToObjectMap) {
switch (propertyType) { switch (propertyType) {
case 'S': case 'S':
// String // String
@ -124,13 +129,19 @@ public final class FBXDump {
case 'R': case 'R':
// RAW data. // RAW data.
byte[] bytes = (byte[]) property; byte[] bytes = (byte[]) property;
ps.print("["); int numToPrint = Math.min(10 * 1024, bytes.length);
for (int j = 0; j < bytes.length; j++) { ps.print("(size = ");
ps.print(bytes.length);
ps.print(") [");
for (int j = 0; j < numToPrint; j++) {
ps.print(String.format("%02X", bytes[j] & 0xff)); ps.print(String.format("%02X", bytes[j] & 0xff));
if (j != bytes.length - 1) { if (j != bytes.length - 1) {
ps.print(" "); ps.print(" ");
} }
} }
if (numToPrint < bytes.length) {
ps.print(" ...");
}
ps.print("]"); ps.print("]");
break; break;
case 'D': case 'D':
@ -158,7 +169,7 @@ public final class FBXDump {
// If this is a connection, decode UID into object name. // If this is a connection, decode UID into object name.
if (id.equals("C")) { if (id.equals("C")) {
Long uid = (Long) property; Long uid = (Long) property;
FBXElement element = uidToObjectMap.get(uid); FbxElement element = uidToObjectMap.get(FbxId.create(uid));
if (element != null) { if (element != null) {
String name = (String) element.properties.get(1); String name = (String) element.properties.get(1);
ps.print("\"" + convertFBXString(name) + "\""); ps.print("\"" + convertFBXString(name) + "\"");
@ -177,7 +188,7 @@ public final class FBXDump {
int length = Array.getLength(property); int length = Array.getLength(property);
for (int j = 0; j < length; j++) { for (int j = 0; j < length; j++) {
Object arrayEntry = Array.get(property, j); Object arrayEntry = Array.get(property, j);
dumpFBXProperty(id, Character.toUpperCase(propertyType), arrayEntry, ps, uidToObjectMap); dumpProperty(id, Character.toUpperCase(propertyType), arrayEntry, ps, uidToObjectMap);
if (j != length - 1) { if (j != length - 1) {
ps.print(","); ps.print(",");
} }
@ -188,24 +199,24 @@ public final class FBXDump {
} }
} }
protected static void dumpFBXElement(FBXElement el, PrintStream ps, protected static void dumpElement(FbxElement el, PrintStream ps,
int indent, Map<Long, FBXElement> uidToObjectMap) { int indent, Map<FbxId, FbxElement> uidToObjectMap) {
// 4 spaces per tab should be OK. // 4 spaces per tab should be OK.
String indentStr = indent(indent * 4); String indentStr = indent(indent * 4);
String textId = el.id; String textId = el.id;
// Properties are called 'P' and connections are called 'C'. // Properties are called 'P' and connections are called 'C'.
if (el.id.equals("P")) { // if (el.id.equals("P")) {
textId = "Property"; // textId = "Property";
} else if (el.id.equals("C")) { // } else if (el.id.equals("C")) {
textId = "Connect"; // textId = "Connect";
} // }
ps.print(indentStr + textId + ": "); ps.print(indentStr + textId + ": ");
for (int i = 0; i < el.properties.size(); i++) { for (int i = 0; i < el.properties.size(); i++) {
Object property = el.properties.get(i); Object property = el.properties.get(i);
char propertyType = el.propertiesTypes[i]; char propertyType = el.propertiesTypes[i];
dumpFBXProperty(el.id, propertyType, property, ps, uidToObjectMap); dumpProperty(el.id, propertyType, property, ps, uidToObjectMap);
if (i != el.properties.size() - 1) { if (i != el.properties.size() - 1) {
ps.print(", "); ps.print(", ");
} }
@ -214,8 +225,8 @@ public final class FBXDump {
ps.println(); ps.println();
} else { } else {
ps.println(" {"); ps.println(" {");
for (FBXElement childElement : el.children) { for (FbxElement childElement : el.children) {
dumpFBXElement(childElement, ps, indent + 1, uidToObjectMap); dumpElement(childElement, ps, indent + 1, uidToObjectMap);
} }
ps.println(indentStr + "}"); ps.println(indentStr + "}");
} }

@ -34,7 +34,7 @@ package com.jme3.scene.plugins.fbx.file;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class FBXElement { public class FbxElement {
public String id; public String id;
public List<Object> properties; public List<Object> properties;
@ -55,10 +55,70 @@ public class FBXElement {
* c - array of unsigned bytes (represented as array of ints) * c - array of unsigned bytes (represented as array of ints)
*/ */
public char[] propertiesTypes; public char[] propertiesTypes;
public List<FBXElement> children = new ArrayList<FBXElement>(); public List<FbxElement> children = new ArrayList<FbxElement>();
public FBXElement(int propsCount) { public FbxElement(int propsCount) {
properties = new ArrayList<Object>(propsCount); this.properties = new ArrayList<Object>(propsCount);
propertiesTypes = new char[propsCount]; this.propertiesTypes = new char[propsCount];
}
public FbxElement getChildById(String name) {
for (FbxElement element : children) {
if (element.id.equals(name)) {
return element;
}
}
return null;
}
public List<FbxElement> getFbxProperties() {
List<FbxElement> props = new ArrayList<FbxElement>();
FbxElement propsElement = null;
boolean legacy = false;
for (FbxElement element : children) {
if (element.id.equals("Properties70")) {
propsElement = element;
break;
} else if (element.id.equals("Properties60")) {
legacy = true;
propsElement = element;
break;
}
}
if (propsElement == null) {
return props;
}
for (FbxElement prop : propsElement.children) {
if (prop.id.equals("P") || prop.id.equals("Property")) {
if (legacy) {
char[] types = new char[prop.propertiesTypes.length + 1];
types[0] = prop.propertiesTypes[0];
types[1] = prop.propertiesTypes[0];
System.arraycopy(prop.propertiesTypes, 1, types, 2, types.length - 2);
List<Object> values = new ArrayList<Object>(prop.properties);
values.add(1, values.get(0));
FbxElement dummyProp = new FbxElement(types.length);
dummyProp.children = prop.children;
dummyProp.id = prop.id;
dummyProp.propertiesTypes = types;
dummyProp.properties = values;
props.add(dummyProp);
} else {
props.add(prop);
}
}
}
return props;
}
@Override
public String toString() {
return "FBXElement[id=" + id + ", numProps=" + properties.size() + ", numChildren=" + children.size() + "]";
} }
} }

@ -34,9 +34,13 @@ package com.jme3.scene.plugins.fbx.file;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class FBXFile { public class FbxFile {
public List<FBXElement> rootElements = new ArrayList<FBXElement>(); public List<FbxElement> rootElements = new ArrayList<FbxElement>();
public long version; public long version;
@Override
public String toString() {
return "FBXFile[version=" + version + ",numElements=" + rootElements.size() + "]";
}
} }

@ -40,7 +40,7 @@ import java.nio.ByteOrder;
import java.util.Arrays; import java.util.Arrays;
import java.util.zip.InflaterInputStream; import java.util.zip.InflaterInputStream;
public class FBXReader { public class FbxReader {
public static final int BLOCK_SENTINEL_LENGTH = 13; public static final int BLOCK_SENTINEL_LENGTH = 13;
public static final byte[] BLOCK_SENTINEL_DATA = new byte[BLOCK_SENTINEL_LENGTH]; public static final byte[] BLOCK_SENTINEL_DATA = new byte[BLOCK_SENTINEL_LENGTH];
@ -50,8 +50,8 @@ public class FBXReader {
*/ */
public static final byte[] HEAD_MAGIC = new byte[]{0x4b, 0x61, 0x79, 0x64, 0x61, 0x72, 0x61, 0x20, 0x46, 0x42, 0x58, 0x20, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x20, 0x00, 0x1a, 0x00}; public static final byte[] HEAD_MAGIC = new byte[]{0x4b, 0x61, 0x79, 0x64, 0x61, 0x72, 0x61, 0x20, 0x46, 0x42, 0x58, 0x20, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x20, 0x00, 0x1a, 0x00};
public static FBXFile readFBX(InputStream stream) throws IOException { public static FbxFile readFBX(InputStream stream) throws IOException {
FBXFile fbxFile = new FBXFile(); FbxFile fbxFile = new FbxFile();
// Read file to byte buffer so we can know current position in file // Read file to byte buffer so we can know current position in file
ByteBuffer byteBuffer = readToByteBuffer(stream); ByteBuffer byteBuffer = readToByteBuffer(stream);
try { try {
@ -61,12 +61,14 @@ public class FBXReader {
// Check majic header // Check majic header
byte[] majic = getBytes(byteBuffer, HEAD_MAGIC.length); byte[] majic = getBytes(byteBuffer, HEAD_MAGIC.length);
if(!Arrays.equals(HEAD_MAGIC, majic)) if(!Arrays.equals(HEAD_MAGIC, majic))
throw new IOException("Not FBX file"); throw new IOException("Either ASCII FBX or corrupt file. "
+ "Only binary FBX files are supported");
// Read version // Read version
fbxFile.version = getUInt(byteBuffer); fbxFile.version = getUInt(byteBuffer);
// Read root elements // Read root elements
while(true) { while(true) {
FBXElement e = readFBXElement(byteBuffer); FbxElement e = readFBXElement(byteBuffer);
if(e == null) if(e == null)
break; break;
fbxFile.rootElements.add(e); fbxFile.rootElements.add(e);
@ -74,14 +76,14 @@ public class FBXReader {
return fbxFile; return fbxFile;
} }
private static FBXElement readFBXElement(ByteBuffer byteBuffer) throws IOException { private static FbxElement readFBXElement(ByteBuffer byteBuffer) throws IOException {
long endOffset = getUInt(byteBuffer); long endOffset = getUInt(byteBuffer);
if(endOffset == 0) if(endOffset == 0)
return null; return null;
long propCount = getUInt(byteBuffer); long propCount = getUInt(byteBuffer);
getUInt(byteBuffer); // Properties length unused getUInt(byteBuffer); // Properties length unused
FBXElement element = new FBXElement((int) propCount); FbxElement element = new FbxElement((int) propCount);
element.id = new String(getBytes(byteBuffer, getUByte(byteBuffer))); element.id = new String(getBytes(byteBuffer, getUByte(byteBuffer)));
for(int i = 0; i < propCount; ++i) { for(int i = 0; i < propCount; ++i) {

Loading…
Cancel
Save