diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/BlenderContext.java b/engine/src/blender/com/jme3/scene/plugins/blender/BlenderContext.java index 22d5312aa..ac8fda76e 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/BlenderContext.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/BlenderContext.java @@ -114,7 +114,9 @@ public class BlenderContext { protected Map boneContexts = new HashMap(); /** A map og helpers that perform loading. */ private Map helpers = new HashMap(); - + /** Markers used by loading classes to store some custom data. This is made to avoid putting this data into user properties. */ + private Map> markers = new HashMap>(); + /** * This method sets the blender file version. * @@ -562,6 +564,44 @@ public class BlenderContext { } return blenderKey.getDefaultMaterial(); } + + /** + * Adds a custom marker for scene's feature. + * + * @param marker + * the marker name + * @param feature + * te scene's feature (can be node, material or texture or + * anything else) + * @param markerValue + * the marker value + */ + public void addMarker(String marker, Object feature, Object markerValue) { + if (markerValue == null) { + throw new IllegalArgumentException("The marker's value cannot be null."); + } + Map markersMap = markers.get(marker); + if (markersMap == null) { + markersMap = new HashMap(); + markers.put(marker, markersMap); + } + markersMap.put(feature, markerValue); + } + + /** + * Returns the marker value. The returned value is null if no marker was + * defined for the given feature. + * + * @param marker + * the marker name + * @param feature + * the scene's feature + * @return marker value or null if it was not defined + */ + public Object getMarkerValue(String marker, Object feature) { + Map markersMap = markers.get(marker); + return markersMap == null ? null : markersMap.get(feature); + } /** * Clears all sotred resources and closes the blender input stream. @@ -580,6 +620,7 @@ public class BlenderContext { helpers.clear(); fileBlockHeadersByOma.clear(); fileBlockHeadersByCode.clear(); + markers.clear(); } /** diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/BoneConstraint.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/BoneConstraint.java index 12229d68c..f73c4a9e4 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/BoneConstraint.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/BoneConstraint.java @@ -51,7 +51,7 @@ import com.jme3.scene.plugins.blender.file.Structure; } // the second part of the if expression verifies if the found node // (if any) is an armature node - if (nodeTarget.getUserData(ArmatureHelper.ARMATURE_NODE_MARKER) != null) { + if (blenderContext.getMarkerValue(ArmatureHelper.ARMATURE_NODE_MARKER, nodeTarget) != null) { if(subtargetName.trim().isEmpty()) { LOGGER.log(Level.WARNING, "No bone target specified for constraint: {0}.", name); return false; diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintHelper.java index e2f3931e9..ecff27880 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintHelper.java @@ -25,6 +25,7 @@ import com.jme3.scene.plugins.blender.animations.IpoHelper; import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; import com.jme3.scene.plugins.blender.file.Pointer; import com.jme3.scene.plugins.blender.file.Structure; +import com.jme3.scene.plugins.blender.objects.ObjectHelper; /** * This class should be used for constraint calculations. @@ -195,7 +196,7 @@ public class ConstraintHelper extends AbstractBlenderHelper { while (spatial.getParent() != null) { spatial = spatial.getParent(); } - simulationRootNodes.add(new SimulationNode((Long) spatial.getUserData("oma"), blenderContext)); + simulationRootNodes.add(new SimulationNode((Long) blenderContext.getMarkerValue(ObjectHelper.OMA_MARKER, spatial), blenderContext)); } else { throw new IllegalStateException("Unsupported constraint type: " + constraint); } @@ -220,7 +221,7 @@ public class ConstraintHelper extends AbstractBlenderHelper { */ public Transform getTransform(Long oma, String subtargetName, Space space) { Spatial feature = (Spatial) blenderContext.getLoadedFeature(oma, LoadedFeatureDataType.LOADED_FEATURE); - boolean isArmature = feature.getUserData(ArmatureHelper.ARMATURE_NODE_MARKER) != null; + boolean isArmature = blenderContext.getMarkerValue(ArmatureHelper.ARMATURE_NODE_MARKER, feature) != null; if (isArmature) { BoneContext targetBoneContext = blenderContext.getBoneByName(subtargetName); Bone bone = targetBoneContext.getBone(); @@ -269,9 +270,9 @@ public class ConstraintHelper extends AbstractBlenderHelper { } else { switch (space) { case CONSTRAINT_SPACE_LOCAL: - return ((Spatial) feature).getLocalTransform(); + return feature.getLocalTransform(); case CONSTRAINT_SPACE_WORLD: - return ((Spatial) feature).getWorldTransform(); + return feature.getWorldTransform(); case CONSTRAINT_SPACE_PARLOCAL: case CONSTRAINT_SPACE_POSE: throw new IllegalStateException("Nodes can have only Local and World spaces applied!"); @@ -297,7 +298,7 @@ public class ConstraintHelper extends AbstractBlenderHelper { */ public void applyTransform(Long oma, String subtargetName, Space space, Transform transform) { Spatial feature = (Spatial) blenderContext.getLoadedFeature(oma, LoadedFeatureDataType.LOADED_FEATURE); - boolean isArmature = feature.getUserData(ArmatureHelper.ARMATURE_NODE_MARKER) != null; + boolean isArmature = blenderContext.getMarkerValue(ArmatureHelper.ARMATURE_NODE_MARKER, feature) != null; if (isArmature) { Skeleton skeleton = blenderContext.getSkeleton(oma); BoneContext targetBoneContext = blenderContext.getBoneByName(subtargetName); @@ -354,17 +355,16 @@ public class ConstraintHelper extends AbstractBlenderHelper { default: throw new IllegalStateException("Invalid space type for target object: " + space.toString()); } - } else if (feature instanceof Spatial) { - Spatial spatial = (Spatial) feature; + } else { switch (space) { case CONSTRAINT_SPACE_LOCAL: - spatial.getLocalTransform().set(transform); + feature.getLocalTransform().set(transform); break; case CONSTRAINT_SPACE_WORLD: - if (spatial.getParent() == null) { - spatial.setLocalTransform(transform); + if (feature.getParent() == null) { + feature.setLocalTransform(transform); } else { - Transform parentWorldTransform = spatial.getParent().getWorldTransform(); + Transform parentWorldTransform = feature.getParent().getWorldTransform(); Matrix4f parentMatrix = this.toMatrix(parentWorldTransform).invertLocal(); Matrix4f m = this.toMatrix(transform); @@ -374,14 +374,12 @@ public class ConstraintHelper extends AbstractBlenderHelper { transform.setRotation(m.toRotationQuat()); transform.setScale(m.toScaleVector()); - spatial.setLocalTransform(transform); + feature.setLocalTransform(transform); } break; default: throw new IllegalStateException("Invalid space type for spatial object: " + space.toString()); } - } else { - throw new IllegalStateException("Constrained transformation can be applied only to Bone or Spatial feature!"); } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/SimulationNode.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/SimulationNode.java index 170e88b30..71696beaa 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/SimulationNode.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/SimulationNode.java @@ -25,6 +25,7 @@ import com.jme3.scene.plugins.blender.BlenderContext; import com.jme3.scene.plugins.blender.BlenderContext.LoadedFeatureDataType; import com.jme3.scene.plugins.blender.animations.ArmatureHelper; import com.jme3.scene.plugins.blender.animations.BoneContext; +import com.jme3.scene.plugins.blender.objects.ObjectHelper; import com.jme3.util.TempVars; /** @@ -89,7 +90,7 @@ public class SimulationNode { */ private SimulationNode(Long featureOMA, BlenderContext blenderContext, boolean rootNode) { Node spatial = (Node) blenderContext.getLoadedFeature(featureOMA, LoadedFeatureDataType.LOADED_FEATURE); - if (spatial.getUserData(ArmatureHelper.ARMATURE_NODE_MARKER) != null) { + if (blenderContext.getMarkerValue(ArmatureHelper.ARMATURE_NODE_MARKER, spatial) != null) { this.skeleton = blenderContext.getSkeleton(featureOMA); Node nodeWithAnimationControl = blenderContext.getControlledNode(skeleton); @@ -135,7 +136,7 @@ public class SimulationNode { animations = blenderContext.getAnimData(featureOMA) == null ? null : blenderContext.getAnimData(featureOMA).anims; for (Spatial child : spatial.getChildren()) { if (child instanceof Node) { - children.add(new SimulationNode((Long) child.getUserData("oma"), blenderContext, false)); + children.add(new SimulationNode((Long) blenderContext.getMarkerValue(ObjectHelper.OMA_MARKER, child), blenderContext, false)); } } } @@ -199,7 +200,7 @@ public class SimulationNode { boolean applyStaticConstraints = true; if (animations != null) { for (Animation animation : animations) { - float[] animationTimeBoundaries = computeAnimationTimeBoundaries(animation); + float[] animationTimeBoundaries = this.computeAnimationTimeBoundaries(animation); int maxFrame = (int) animationTimeBoundaries[0]; float maxTime = animationTimeBoundaries[1]; diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/objects/ObjectHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/objects/ObjectHelper.java index 5b13ddce2..595153b2c 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/objects/ObjectHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/objects/ObjectHelper.java @@ -83,6 +83,8 @@ public class ObjectHelper extends AbstractBlenderHelper { protected static final int OBJECT_TYPE_WAVE = 21; protected static final int OBJECT_TYPE_LATTICE = 22; protected static final int OBJECT_TYPE_ARMATURE = 25; + + public static final String OMA_MARKER = "oma"; /** * This constructor parses the given blender version and stores the result. @@ -214,7 +216,7 @@ public class ObjectHelper extends AbstractBlenderHelper { // parent-children relationships between nodes Node armature = new Node(name); armature.setLocalTransform(t); - armature.setUserData(ArmatureHelper.ARMATURE_NODE_MARKER, Boolean.TRUE); + blenderContext.addMarker(ArmatureHelper.ARMATURE_NODE_MARKER, armature, Boolean.TRUE); if (parent instanceof Node) { ((Node) parent).attachChild(armature); @@ -233,9 +235,7 @@ public class ObjectHelper extends AbstractBlenderHelper { result.updateModelBound(); blenderContext.addLoadedFeatures(objectStructure.getOldMemoryAddress(), name, objectStructure, result); - // TODO: this data is only to help during loading, shall I remove it - // after all the loading is done ??? - result.setUserData("oma", objectStructure.getOldMemoryAddress()); + blenderContext.addMarker(OMA_MARKER, result, objectStructure.getOldMemoryAddress()); // applying modifiers LOGGER.log(Level.FINE, "Reading and applying object's modifiers.");