|
@@ -44,6 +44,7 @@ import com.jme3.math.Transform;
|
|
import com.jme3.math.Vector3f;
|
|
import com.jme3.math.Vector3f;
|
|
import com.jme3.scene.Geometry;
|
|
import com.jme3.scene.Geometry;
|
|
import com.jme3.scene.Node;
|
|
import com.jme3.scene.Node;
|
|
|
|
+import com.jme3.scene.Spatial;
|
|
import com.jme3.scene.Spatial.CullHint;
|
|
import com.jme3.scene.Spatial.CullHint;
|
|
import com.jme3.scene.plugins.blender.AbstractBlenderHelper;
|
|
import com.jme3.scene.plugins.blender.AbstractBlenderHelper;
|
|
import com.jme3.scene.plugins.blender.BlenderContext;
|
|
import com.jme3.scene.plugins.blender.BlenderContext;
|
|
@@ -67,9 +68,9 @@ import com.jme3.scene.plugins.blender.modifiers.ModifierHelper;
|
|
* @author Marcin Roguski (Kaelthas)
|
|
* @author Marcin Roguski (Kaelthas)
|
|
*/
|
|
*/
|
|
public class ObjectHelper extends AbstractBlenderHelper {
|
|
public class ObjectHelper extends AbstractBlenderHelper {
|
|
- private static final Logger LOGGER = Logger.getLogger(ObjectHelper.class.getName());
|
|
|
|
|
|
+ private static final Logger LOGGER = Logger.getLogger(ObjectHelper.class.getName());
|
|
|
|
|
|
- public static final String OMA_MARKER = "oma";
|
|
|
|
|
|
+ public static final String OMA_MARKER = "oma";
|
|
|
|
|
|
/**
|
|
/**
|
|
* This constructor parses the given blender version and stores the result.
|
|
* This constructor parses the given blender version and stores the result.
|
|
@@ -98,28 +99,28 @@ public class ObjectHelper extends AbstractBlenderHelper {
|
|
*/
|
|
*/
|
|
public Object toObject(Structure objectStructure, BlenderContext blenderContext) throws BlenderFileException {
|
|
public Object toObject(Structure objectStructure, BlenderContext blenderContext) throws BlenderFileException {
|
|
LOGGER.fine("Loading blender object.");
|
|
LOGGER.fine("Loading blender object.");
|
|
-
|
|
|
|
|
|
+
|
|
int type = ((Number) objectStructure.getFieldValue("type")).intValue();
|
|
int type = ((Number) objectStructure.getFieldValue("type")).intValue();
|
|
ObjectType objectType = ObjectType.valueOf(type);
|
|
ObjectType objectType = ObjectType.valueOf(type);
|
|
LOGGER.log(Level.FINE, "Type of the object: {0}.", objectType);
|
|
LOGGER.log(Level.FINE, "Type of the object: {0}.", objectType);
|
|
- if(objectType == ObjectType.LAMP && !blenderContext.getBlenderKey().shouldLoad(FeaturesToLoad.LIGHTS)) {
|
|
|
|
|
|
+ if (objectType == ObjectType.LAMP && !blenderContext.getBlenderKey().shouldLoad(FeaturesToLoad.LIGHTS)) {
|
|
LOGGER.fine("Lamps are not included in loading.");
|
|
LOGGER.fine("Lamps are not included in loading.");
|
|
return null;
|
|
return null;
|
|
}
|
|
}
|
|
- if(objectType == ObjectType.CAMERA && !blenderContext.getBlenderKey().shouldLoad(FeaturesToLoad.CAMERAS)) {
|
|
|
|
|
|
+ if (objectType == ObjectType.CAMERA && !blenderContext.getBlenderKey().shouldLoad(FeaturesToLoad.CAMERAS)) {
|
|
LOGGER.fine("Cameras are not included in loading.");
|
|
LOGGER.fine("Cameras are not included in loading.");
|
|
return null;
|
|
return null;
|
|
}
|
|
}
|
|
- if(!blenderContext.getBlenderKey().shouldLoad(FeaturesToLoad.OBJECTS)) {
|
|
|
|
|
|
+ if (!blenderContext.getBlenderKey().shouldLoad(FeaturesToLoad.OBJECTS)) {
|
|
LOGGER.fine("Objects are not included in loading.");
|
|
LOGGER.fine("Objects are not included in loading.");
|
|
return null;
|
|
return null;
|
|
- }
|
|
|
|
|
|
+ }
|
|
int lay = ((Number) objectStructure.getFieldValue("lay")).intValue();
|
|
int lay = ((Number) objectStructure.getFieldValue("lay")).intValue();
|
|
- if((lay & blenderContext.getBlenderKey().getLayersToLoad()) == 0) {
|
|
|
|
|
|
+ if ((lay & blenderContext.getBlenderKey().getLayersToLoad()) == 0) {
|
|
LOGGER.fine("The layer this object is located in is not included in loading.");
|
|
LOGGER.fine("The layer this object is located in is not included in loading.");
|
|
return null;
|
|
return null;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
LOGGER.fine("Checking if the object has not been already loaded.");
|
|
LOGGER.fine("Checking if the object has not been already loaded.");
|
|
Object loadedResult = blenderContext.getLoadedFeature(objectStructure.getOldMemoryAddress(), LoadedFeatureDataType.LOADED_FEATURE);
|
|
Object loadedResult = blenderContext.getLoadedFeature(objectStructure.getOldMemoryAddress(), LoadedFeatureDataType.LOADED_FEATURE);
|
|
if (loadedResult != null) {
|
|
if (loadedResult != null) {
|
|
@@ -201,29 +202,29 @@ public class ObjectHelper extends AbstractBlenderHelper {
|
|
|
|
|
|
if (result != null) {
|
|
if (result != null) {
|
|
blenderContext.addLoadedFeatures(objectStructure.getOldMemoryAddress(), name, objectStructure, result);
|
|
blenderContext.addLoadedFeatures(objectStructure.getOldMemoryAddress(), name, objectStructure, result);
|
|
-
|
|
|
|
|
|
+
|
|
result.setLocalTransform(t);
|
|
result.setLocalTransform(t);
|
|
result.setCullHint(visible ? CullHint.Always : CullHint.Inherit);
|
|
result.setCullHint(visible ? CullHint.Always : CullHint.Inherit);
|
|
if (parent instanceof Node) {
|
|
if (parent instanceof Node) {
|
|
((Node) parent).attachChild(result);
|
|
((Node) parent).attachChild(result);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
LOGGER.fine("Reading and applying object's modifiers.");
|
|
LOGGER.fine("Reading and applying object's modifiers.");
|
|
ModifierHelper modifierHelper = blenderContext.getHelper(ModifierHelper.class);
|
|
ModifierHelper modifierHelper = blenderContext.getHelper(ModifierHelper.class);
|
|
Collection<Modifier> modifiers = modifierHelper.readModifiers(objectStructure, blenderContext);
|
|
Collection<Modifier> modifiers = modifierHelper.readModifiers(objectStructure, blenderContext);
|
|
for (Modifier modifier : modifiers) {
|
|
for (Modifier modifier : modifiers) {
|
|
modifier.apply(result, blenderContext);
|
|
modifier.apply(result, blenderContext);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
// I prefer do compute bounding box here than read it from the file
|
|
// I prefer do compute bounding box here than read it from the file
|
|
result.updateModelBound();
|
|
result.updateModelBound();
|
|
-
|
|
|
|
|
|
+
|
|
LOGGER.fine("Applying markers (those will be removed before the final result is released).");
|
|
LOGGER.fine("Applying markers (those will be removed before the final result is released).");
|
|
blenderContext.addMarker(OMA_MARKER, result, objectStructure.getOldMemoryAddress());
|
|
blenderContext.addMarker(OMA_MARKER, result, objectStructure.getOldMemoryAddress());
|
|
- if(objectType == ObjectType.ARMATURE) {
|
|
|
|
|
|
+ if (objectType == ObjectType.ARMATURE) {
|
|
blenderContext.addMarker(ArmatureHelper.ARMATURE_NODE_MARKER, result, Boolean.TRUE);
|
|
blenderContext.addMarker(ArmatureHelper.ARMATURE_NODE_MARKER, result, Boolean.TRUE);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
LOGGER.fine("Loading constraints connected with this object.");
|
|
LOGGER.fine("Loading constraints connected with this object.");
|
|
ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class);
|
|
ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class);
|
|
constraintHelper.loadConstraints(objectStructure, blenderContext);
|
|
constraintHelper.loadConstraints(objectStructure, blenderContext);
|
|
@@ -241,6 +242,31 @@ public class ObjectHelper extends AbstractBlenderHelper {
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Checks if the first given OMA points to a parent of the second one.
|
|
|
|
+ * The parent need not to be the direct one. This method should be called when we are sure
|
|
|
|
+ * that both of the features are alred loaded because it does not check it.
|
|
|
|
+ * The OMA's should point to a spatials, otherwise the function will throw ClassCastException.
|
|
|
|
+ * @param supposedParentOMA
|
|
|
|
+ * the OMA of the node that we suppose might be a parent of the second one
|
|
|
|
+ * @param spatialOMA
|
|
|
|
+ * the OMA of the scene's node
|
|
|
|
+ * @return <b>true</b> if the first given OMA points to a parent of the second one and <b>false</b> otherwise
|
|
|
|
+ */
|
|
|
|
+ public boolean isParent(Long supposedParentOMA, Long spatialOMA) {
|
|
|
|
+ Spatial supposedParent = (Spatial) blenderContext.getLoadedFeature(supposedParentOMA, LoadedFeatureDataType.LOADED_FEATURE);
|
|
|
|
+ Spatial spatial = (Spatial) blenderContext.getLoadedFeature(spatialOMA, LoadedFeatureDataType.LOADED_FEATURE);
|
|
|
|
+
|
|
|
|
+ Spatial parent = spatial.getParent();
|
|
|
|
+ while (parent != null) {
|
|
|
|
+ if (parent.equals(supposedParent)) {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ parent = parent.getParent();
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* This method calculates local transformation for the object. Parentage is
|
|
* This method calculates local transformation for the object. Parentage is
|
|
* taken under consideration.
|
|
* taken under consideration.
|
|
@@ -320,7 +346,7 @@ public class ObjectHelper extends AbstractBlenderHelper {
|
|
public Matrix4f getMatrix(Structure structure, String matrixName, boolean applyFixUpAxis) {
|
|
public Matrix4f getMatrix(Structure structure, String matrixName, boolean applyFixUpAxis) {
|
|
Matrix4f result = new Matrix4f();
|
|
Matrix4f result = new Matrix4f();
|
|
DynamicArray<Number> obmat = (DynamicArray<Number>) structure.getFieldValue(matrixName);
|
|
DynamicArray<Number> obmat = (DynamicArray<Number>) structure.getFieldValue(matrixName);
|
|
- //the matrix must be square
|
|
|
|
|
|
+ // the matrix must be square
|
|
int rowAndColumnSize = Math.abs((int) Math.sqrt(obmat.getTotalSize()));
|
|
int rowAndColumnSize = Math.abs((int) Math.sqrt(obmat.getTotalSize()));
|
|
for (int i = 0; i < rowAndColumnSize; ++i) {
|
|
for (int i = 0; i < rowAndColumnSize; ++i) {
|
|
for (int j = 0; j < rowAndColumnSize; ++j) {
|
|
for (int j = 0; j < rowAndColumnSize; ++j) {
|
|
@@ -361,29 +387,19 @@ public class ObjectHelper extends AbstractBlenderHelper {
|
|
|
|
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
private static enum ObjectType {
|
|
private static enum ObjectType {
|
|
- EMPTY(0),
|
|
|
|
- MESH(1),
|
|
|
|
- CURVE(2),
|
|
|
|
- SURF(3),
|
|
|
|
- TEXT(4),
|
|
|
|
- METABALL(5),
|
|
|
|
- LAMP(10),
|
|
|
|
- CAMERA(11),
|
|
|
|
- WAVE(21),
|
|
|
|
- LATTICE(22),
|
|
|
|
- ARMATURE(25);
|
|
|
|
-
|
|
|
|
|
|
+ EMPTY(0), MESH(1), CURVE(2), SURF(3), TEXT(4), METABALL(5), LAMP(10), CAMERA(11), WAVE(21), LATTICE(22), ARMATURE(25);
|
|
|
|
+
|
|
private int blenderTypeValue;
|
|
private int blenderTypeValue;
|
|
-
|
|
|
|
|
|
+
|
|
private ObjectType(int blenderTypeValue) {
|
|
private ObjectType(int blenderTypeValue) {
|
|
this.blenderTypeValue = blenderTypeValue;
|
|
this.blenderTypeValue = blenderTypeValue;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
public static ObjectType valueOf(int blenderTypeValue) throws BlenderFileException {
|
|
public static ObjectType valueOf(int blenderTypeValue) throws BlenderFileException {
|
|
- for(ObjectType type : ObjectType.values()) {
|
|
|
|
- if(type.blenderTypeValue == blenderTypeValue) {
|
|
|
|
|
|
+ for (ObjectType type : ObjectType.values()) {
|
|
|
|
+ if (type.blenderTypeValue == blenderTypeValue) {
|
|
return type;
|
|
return type;
|
|
}
|
|
}
|
|
}
|
|
}
|