Просмотр исходного кода

Huge constraints refactoring (the computations might yet not be perfect, but models loading should get much less crashes).

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9720 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
Kae..pl 13 лет назад
Родитель
Сommit
711b8ab9ca
65 измененных файлов с 2095 добавлено и 2327 удалено
  1. 31 1
      engine/src/blender/com/jme3/scene/plugins/blender/BlenderContext.java
  2. 12 1
      engine/src/blender/com/jme3/scene/plugins/blender/BlenderLoader.java
  3. 6 0
      engine/src/blender/com/jme3/scene/plugins/blender/BlenderModelLoader.java
  4. 7 0
      engine/src/blender/com/jme3/scene/plugins/blender/animations/BoneContext.java
  5. 0 142
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/BlenderTrack.java
  6. 168 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/BoneConstraint.java
  7. 61 88
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/Constraint.java
  8. 0 42
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintAction.java
  9. 0 42
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintChildOf.java
  10. 0 43
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintClampTo.java
  11. 0 42
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintDampTrack.java
  12. 0 120
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintDistLimit.java
  13. 0 42
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintFollowPath.java
  14. 353 84
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintHelper.java
  15. 0 122
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLocLike.java
  16. 0 137
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLocLimit.java
  17. 0 43
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLockTrack.java
  18. 0 42
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintMinMax.java
  19. 0 37
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintNull.java
  20. 0 43
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintPivot.java
  21. 0 42
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintPython.java
  22. 0 42
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRigidBodyJoint.java
  23. 0 114
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRotLike.java
  24. 0 180
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRotLimit.java
  25. 0 45
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSameVolume.java
  26. 0 98
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSizeLike.java
  27. 0 131
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSizeLimit.java
  28. 0 43
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSplineInverseKinematic.java
  29. 0 42
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintStretchTo.java
  30. 0 45
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintTrackTo.java
  31. 0 45
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintTransLike.java
  32. 0 42
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintTransform.java
  33. 0 302
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/Feature.java
  34. 32 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/SkeletonConstraint.java
  35. 146 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/SpatialConstraint.java
  36. 244 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinition.java
  37. 26 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionAction.java
  38. 26 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionChildOf.java
  39. 26 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionClampTo.java
  40. 26 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionDampTrack.java
  41. 59 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionDistLimit.java
  42. 83 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionFactory.java
  43. 26 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionFollowPath.java
  44. 8 26
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionInverseKinematics.java
  45. 74 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionLocLike.java
  46. 87 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionLocLimit.java
  47. 26 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionLockTrack.java
  48. 26 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionMinMax.java
  49. 19 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionNull.java
  50. 26 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionPivot.java
  51. 26 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionPython.java
  52. 26 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionRigidBodyJoint.java
  53. 67 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionRotLike.java
  54. 85 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionRotLimit.java
  55. 27 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionSameVolume.java
  56. 8 37
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionShrinkWrap.java
  57. 51 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionSizeLike.java
  58. 75 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionSizeLimit.java
  59. 26 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionSplineInverseKinematic.java
  60. 26 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionStretchTo.java
  61. 27 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionTrackTo.java
  62. 27 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionTransLike.java
  63. 26 0
      engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionTransform.java
  64. 0 13
      engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ArmatureModifier.java
  65. 0 9
      engine/src/blender/com/jme3/scene/plugins/blender/objects/ObjectHelper.java

+ 31 - 1
engine/src/blender/com/jme3/scene/plugins/blender/BlenderContext.java

@@ -31,6 +31,7 @@
  */
 package com.jme3.scene.plugins.blender;
 
+import com.jme3.animation.Bone;
 import com.jme3.animation.Skeleton;
 import com.jme3.asset.AssetManager;
 import com.jme3.asset.BlenderKey;
@@ -52,6 +53,7 @@ import java.util.EmptyStackException;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Stack;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -488,6 +490,17 @@ public class BlenderContext {
 	public List<Constraint> getConstraints(Long objectOMA) {
 		return objectOMA == null ? null : constraints.get(objectOMA);
 	}
+	
+	/**
+	 * @return all available constraints
+	 */
+	public List<Constraint> getAllConstraints() {
+		List<Constraint> result = new ArrayList<Constraint>();
+		for(Entry<Long, List<Constraint>> entry : constraints.entrySet()) {
+			result.addAll(entry.getValue());
+		}
+		return result;
+	}
 
 	/**
 	 * This method sets the anim data for the specified OMA of its owner.
@@ -584,7 +597,24 @@ public class BlenderContext {
 	public BoneContext getBoneContext(Long boneOMA) {
 		return boneContexts.get(boneOMA);
 	}
-
+	
+	/**
+	 * Returns bone by given name.
+	 * 
+	 * @param name
+	 *            the name of the bone
+	 * @return found bone or null if none bone of a given name exists
+	 */
+	public BoneContext getBoneByName(String name) {
+		for(Entry<Long, BoneContext> entry : boneContexts.entrySet()) {
+			Bone bone = entry.getValue().getBone();
+			if(bone != null && name.equals(bone.getName())) {
+				return entry.getValue();
+			}
+		}
+		return null;
+	}
+	
 	/**
 	 * This metod returns the default material.
 	 * 

+ 12 - 1
engine/src/blender/com/jme3/scene/plugins/blender/BlenderLoader.java

@@ -79,6 +79,7 @@ public class BlenderLoader extends AbstractBlenderLoader {
 		try {
 			this.setup(assetInfo);
 
+			List<FileBlockHeader> sceneBlocks = new ArrayList<FileBlockHeader>();
 			BlenderKey blenderKey = blenderContext.getBlenderKey();
 			LoadingResults loadingResults = blenderKey.prepareLoadingResults();
 			WorldData worldData = null;// a set of data used in different scene aspects
@@ -104,7 +105,7 @@ public class BlenderLoader extends AbstractBlenderLoader {
 //						break;
 					case FileBlockHeader.BLOCK_SC00:// Scene
 						if ((blenderKey.getFeaturesToLoad() & FeaturesToLoad.SCENES) != 0) {
-							loadingResults.addScene(this.toScene(block.getStructure(blenderContext)));
+							sceneBlocks.add(block);
 						}
 						break;
 					case FileBlockHeader.BLOCK_WO00:// World
@@ -121,6 +122,16 @@ public class BlenderLoader extends AbstractBlenderLoader {
 						break;
 				}
 			}
+			
+			//bake constraints after everything is loaded
+			ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class);
+			constraintHelper.bakeConstraints(blenderContext);
+			
+			//load the scene at the very end so that the root nodes have no parent during loading or constraints applying
+			for(FileBlockHeader sceneBlock : sceneBlocks) {
+				loadingResults.addScene(this.toScene(sceneBlock.getStructure(blenderContext)));
+			}
+			
 			blenderContext.dispose();
 			return loadingResults;
 		} catch (BlenderFileException e) {

+ 6 - 0
engine/src/blender/com/jme3/scene/plugins/blender/BlenderModelLoader.java

@@ -41,6 +41,7 @@ import com.jme3.asset.BlenderKey.FeaturesToLoad;
 import com.jme3.scene.LightNode;
 import com.jme3.scene.Node;
 import com.jme3.scene.Spatial;
+import com.jme3.scene.plugins.blender.constraints.ConstraintHelper;
 import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
 import com.jme3.scene.plugins.blender.file.FileBlockHeader;
 
@@ -75,6 +76,11 @@ public class BlenderModelLoader extends BlenderLoader {
 					}
                 }
             }
+            
+            //bake constraints after everything is loaded
+			ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class);
+			constraintHelper.bakeConstraints(blenderContext);
+            
             blenderContext.dispose();
             return modelRoot;
         } catch (BlenderFileException e) {

+ 7 - 0
engine/src/blender/com/jme3/scene/plugins/blender/animations/BoneContext.java

@@ -200,4 +200,11 @@ public class BoneContext {
 	public Bone getBone() {
 		return bone;
 	}
+	
+	/**
+	 * @return the old memory address of the bone
+	 */
+	public Long getBoneOma() {
+		return boneStructure.getOldMemoryAddress();	
+	}
 }

+ 0 - 142
engine/src/blender/com/jme3/scene/plugins/blender/constraints/BlenderTrack.java

@@ -1,142 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import com.jme3.animation.AnimChannel;
-import com.jme3.animation.AnimControl;
-import com.jme3.animation.BoneTrack;
-import com.jme3.animation.SpatialTrack;
-import com.jme3.animation.Track;
-import com.jme3.export.JmeExporter;
-import com.jme3.export.JmeImporter;
-import com.jme3.math.Quaternion;
-import com.jme3.math.Vector3f;
-import com.jme3.util.TempVars;
-import java.io.IOException;
-
-/**
- * This class holds either the bone track or spatial track. Is made to improve
- * code readability.
- * 
- * @author Marcin Roguski (Kaelthas)
- */
-/* package */final class BlenderTrack implements Track {
-	/** The spatial track. */
-	private SpatialTrack spatialTrack;
-	/** The bone track. */
-	private BoneTrack boneTrack;
-
-	/**
-	 * Constructs the object using spatial track (bone track is null).
-	 * 
-	 * @param spatialTrack
-	 *            the spatial track
-	 */
-	public BlenderTrack(SpatialTrack spatialTrack) {
-		this.spatialTrack = spatialTrack;
-	}
-
-	/**
-	 * Constructs the object using bone track (spatial track is null).
-	 * 
-	 * @param spatialTrack
-	 *            the spatial track
-	 */
-	public BlenderTrack(BoneTrack boneTrack) {
-		this.boneTrack = boneTrack;
-	}
-
-	/**
-	 * @return the stored track (either bone or spatial)
-	 */
-	public Track getTrack() {
-		return boneTrack != null ? boneTrack : spatialTrack;
-	}
-
-	/**
-	 * @return the array of rotations of this track
-	 */
-	public Quaternion[] getRotations() {
-		if (boneTrack != null) {
-			return boneTrack.getRotations();
-		}
-		return spatialTrack.getRotations();
-	}
-
-	/**
-	 * @return the array of scales for this track
-	 */
-	public Vector3f[] getScales() {
-		if (boneTrack != null) {
-			return boneTrack.getScales();
-		}
-		return spatialTrack.getScales();
-	}
-
-	/**
-	 * @return the arrays of time for this track
-	 */
-	public float[] getTimes() {
-		if (boneTrack != null) {
-			return boneTrack.getTimes();
-		}
-		return spatialTrack.getTimes();
-	}
-
-	/**
-	 * @return the array of translations of this track
-	 */
-	public Vector3f[] getTranslations() {
-		if (boneTrack != null) {
-			return boneTrack.getTranslations();
-		}
-		return spatialTrack.getTranslations();
-	}
-
-	/**
-	 * Set the translations, rotations and scales for this bone track
-	 * 
-	 * @param times
-	 *            a float array with the time of each frame
-	 * @param translations
-	 *            the translation of the bone for each frame
-	 * @param rotations
-	 *            the rotation of the bone for each frame
-	 * @param scales
-	 *            the scale of the bone for each frame
-	 */
-	public void setKeyframes(float[] times, Vector3f[] translations,
-			Quaternion[] rotations, Vector3f[] scales) {
-		if (boneTrack != null) {
-			boneTrack.setKeyframes(times, translations, rotations, scales);
-		} else {
-			spatialTrack.setKeyframes(times, translations, rotations, scales);
-		}
-	}
-
-	public void write(JmeExporter ex) throws IOException {
-	}
-
-	public void read(JmeImporter im) throws IOException {
-	}
-
-	public void setTime(float time, float weight, AnimControl control,
-			AnimChannel channel, TempVars vars) {
-		if (boneTrack != null) {
-			boneTrack.setTime(time, weight, control, channel, vars);
-		} else {
-			spatialTrack.setTime(time, weight, control, channel, vars);
-		}
-	}
-
-	public float getLength() {
-		return spatialTrack == null ? boneTrack.getLength() : spatialTrack
-				.getLength();
-	}
-
-	@Override
-	public BlenderTrack clone() {
-		if (boneTrack != null) {
-			return new BlenderTrack(boneTrack.clone());
-		}
-		return new BlenderTrack(spatialTrack.clone());
-	}
-}

+ 168 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/BoneConstraint.java

@@ -0,0 +1,168 @@
+package com.jme3.scene.plugins.blender.constraints;
+
+import java.util.Arrays;
+import java.util.logging.Logger;
+
+import com.jme3.animation.Animation;
+import com.jme3.animation.Bone;
+import com.jme3.animation.BoneTrack;
+import com.jme3.animation.Track;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Transform;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.BlenderContext.LoadedFeatureDataType;
+import com.jme3.scene.plugins.blender.animations.BoneContext;
+import com.jme3.scene.plugins.blender.animations.Ipo;
+import com.jme3.scene.plugins.blender.constraints.ConstraintHelper.Space;
+import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
+import com.jme3.scene.plugins.blender.file.Structure;
+import com.jme3.scene.plugins.blender.objects.ObjectHelper;
+import com.jme3.scene.plugins.ogre.AnimData;
+
+/**
+ * Constraint applied on the bone.
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class BoneConstraint extends Constraint {
+	private static final Logger LOGGER = Logger.getLogger(BoneConstraint.class.getName());
+	/** The OMA of the target armature. */
+	private Long targetArmatureOMA;
+	
+	public BoneConstraint(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext)
+			throws BlenderFileException {
+		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
+		targetArmatureOMA = targetOMA;
+		if(targetArmatureOMA != null && targetArmatureOMA <= 0L) {
+			targetArmatureOMA = null;
+		}
+		targetOMA = null;
+		if(targetArmatureOMA != null && targetArmatureOMA > 0L && (subtargetName == null || subtargetName.length() == 0)) {
+			invalid = true;
+		}
+	}
+
+	@Override
+	public void performBakingOperation() {
+		Bone owner = blenderContext.getBoneContext(ownerOMA).getBone();
+		Bone target = null;
+		
+		if(targetArmatureOMA != null) {//first make sure the target is loaded
+			ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
+			try {
+				objectHelper.toObject((Structure) blenderContext.getLoadedFeature(targetArmatureOMA, LoadedFeatureDataType.LOADED_STRUCTURE), blenderContext);
+			} catch (BlenderFileException e) {
+				LOGGER.warning("Problems occured during target object loading. The constraint " + name + " will not be applied.");
+				return ;
+			}
+			
+			BoneContext boneContext = blenderContext.getBoneByName(subtargetName);
+			target = boneContext.getBone();
+			this.targetOMA = boneContext.getBoneOma();
+		}
+		
+		this.prepareTracksForApplyingConstraints();
+		AnimData animData = blenderContext.getAnimData(ownerOMA);
+		if(animData != null) {
+			for(Animation animation : animData.anims) {
+				Transform ownerTransform = constraintHelper.getBoneTransform(ownerSpace, owner);
+				Transform targetTransform = target != null ? constraintHelper.getBoneTransform(targetSpace, target) : null;
+				
+				BoneTrack boneTrack = constraintHelper.getTrack(owner, animData.skeleton, animation);
+				BoneTrack targetTrack = target != null ? constraintHelper.getTrack(target, animData.skeleton, animation) : null;
+				
+				constraintDefinition.bake(ownerTransform, targetTransform, boneTrack, targetTrack, this.ipo);
+			}
+		}
+	}
+	
+	@Override
+	protected void prepareTracksForApplyingConstraints() {
+		Long[] bonesOMAs = new Long[] { ownerOMA, targetOMA };
+		Space[] spaces = new Space[] { ownerSpace, targetSpace };
+		
+		//creating animations for current objects if at least on of their parents have an animation
+		for(int i=0;i<bonesOMAs.length;++i) {
+			Long oma = bonesOMAs[i];
+			if(this.hasAnimation(oma)) {
+				Bone currentBone = blenderContext.getBoneContext(oma).getBone();
+				Bone parent = currentBone.getParent();
+				boolean foundAnimation = false;
+				AnimData animData = null;
+				while(parent != null && !foundAnimation) {
+					BoneContext boneContext = blenderContext.getBoneByName(parent.getName());
+					foundAnimation = this.hasAnimation(boneContext.getBoneOma());
+					animData = blenderContext.getAnimData(boneContext.getBoneOma());
+					parent = parent.getParent();
+				}
+				
+				if(foundAnimation) {
+					this.applyAnimData(blenderContext.getBoneContext(oma), spaces[i], animData);
+				}
+			}
+		}
+		
+		//creating animation for owner if it doesn't have one already and if the target has it
+		if(!this.hasAnimation(ownerOMA) && this.hasAnimation(targetOMA)) {
+			AnimData targetAnimData = blenderContext.getAnimData(targetOMA);
+			this.applyAnimData(blenderContext.getBoneContext(ownerOMA), ownerSpace, targetAnimData);
+		}
+	}
+	
+	/**
+	 * The method determines if the bone has animations.
+	 * 
+	 * @param boneOMA
+	 *            OMA of the bone
+	 * @return <b>true</b> if the bone has animations and <b>false</b> otherwise
+	 */
+	private boolean hasAnimation(Long boneOMA) {
+		AnimData animData = blenderContext.getAnimData(boneOMA);
+		if(animData != null) {
+			Bone bone = blenderContext.getBoneContext(boneOMA).getBone();
+			int boneIndex = animData.skeleton.getBoneIndex(bone);
+			for(Animation animation : animData.anims) {
+				for(Track track : animation.getTracks()) {
+					if(track instanceof BoneTrack && ((BoneTrack) track).getTargetBoneIndex() == boneIndex) {
+						return true;
+					}
+				}
+			}
+		}
+		return false;
+	}
+	
+	/**
+	 * The method applies bone's current position to all of the traces of the
+	 * given animations.
+	 * 
+	 * @param boneContext
+	 *            the bone context
+	 * @param space
+	 *            the bone's evaluation space
+	 * @param referenceAnimData
+	 *            the object containing the animations
+	 */
+	private void applyAnimData(BoneContext boneContext, Space space, AnimData referenceAnimData) {
+		ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class);
+		Transform transform = constraintHelper.getBoneTransform(space, boneContext.getBone());
+		
+		AnimData animData = blenderContext.getAnimData(boneContext.getBoneOma());
+		
+		for(Animation animation : referenceAnimData.anims) {
+			BoneTrack parentTrack = (BoneTrack) animation.getTracks()[0];
+			
+			float[] times = parentTrack.getTimes();
+			Vector3f[] translations = new Vector3f[times.length];
+			Quaternion[] rotations = new Quaternion[times.length];
+			Vector3f[] scales = new Vector3f[times.length];
+			Arrays.fill(translations, transform.getTranslation());
+			Arrays.fill(rotations, transform.getRotation());
+			Arrays.fill(scales, transform.getScale());
+			for(Animation anim : animData.anims) {
+				anim.addTrack(new BoneTrack(animData.skeleton.getBoneIndex(boneContext.getBone()), times, translations, rotations, scales));
+			}
+		}
+		blenderContext.setAnimData(boneContext.getBoneOma(), animData);
+	}
+}

+ 61 - 88
engine/src/blender/com/jme3/scene/plugins/blender/constraints/Constraint.java

@@ -1,18 +1,17 @@
 package com.jme3.scene.plugins.blender.constraints;
 
-import com.jme3.animation.Animation;
-import com.jme3.animation.Bone;
-import com.jme3.animation.BoneTrack;
-import com.jme3.animation.Skeleton;
-import com.jme3.animation.SpatialTrack;
-import com.jme3.animation.Track;
-import com.jme3.scene.Spatial;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
 import com.jme3.scene.plugins.blender.BlenderContext;
 import com.jme3.scene.plugins.blender.animations.Ipo;
+import com.jme3.scene.plugins.blender.constraints.ConstraintHelper.Space;
+import com.jme3.scene.plugins.blender.constraints.definitions.ConstraintDefinition;
+import com.jme3.scene.plugins.blender.constraints.definitions.ConstraintDefinitionFactory;
 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;
 
 /**
  * The implementation of a constraint.
@@ -20,18 +19,28 @@ import com.jme3.scene.plugins.blender.objects.ObjectHelper;
  * @author Marcin Roguski (Kaelthas)
  */
 public abstract class Constraint {
+	private static final Logger LOGGER = Logger.getLogger(Constraint.class.getName());
+	
+	/** Indicates if the constraint is invalid. */
+	protected boolean invalid;
 	/** The name of this constraint. */
 	protected final String name;
-	/** The constraint's owner. */
-	protected final Feature owner;
-	/** The constraint's target. */
-	protected final Feature target;
-	/** The structure with constraint's data. */
-	protected final Structure data;
+	/** Indicates if the constraint is already baked or not. */
+	protected boolean baked;
+	
+	protected Space ownerSpace;
+	protected final ConstraintDefinition constraintDefinition;
+	protected Long ownerOMA;
+	
+	protected Long targetOMA;
+	protected Space targetSpace;
+	protected String subtargetName;
+	
 	/** The ipo object defining influence. */
 	protected final Ipo ipo;
 	/** The blender context. */
 	protected final BlenderContext blenderContext;
+	protected final ConstraintHelper constraintHelper;
 	
 	/**
 	 * This constructor creates the constraint instance.
@@ -48,100 +57,64 @@ public abstract class Constraint {
 	 *             this exception is thrown when the blender file is somehow
 	 *             corrupted
 	 */
-	public Constraint(Structure constraintStructure, Long ownerOMA,
-			Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
+	public Constraint(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
 		this.blenderContext = blenderContext;
 		this.name = constraintStructure.getFieldValue("name").toString();
 		Pointer pData = (Pointer) constraintStructure.getFieldValue("data");
 		if (pData.isNotNull()) {
-			data = pData.fetchData(blenderContext.getInputStream()).get(0);
+			Structure data = pData.fetchData(blenderContext.getInputStream()).get(0);
+			constraintDefinition = ConstraintDefinitionFactory.createConstraintDefinition(data, blenderContext);
 			Pointer pTar = (Pointer)data.getFieldValue("tar");
 			if(pTar!= null && pTar.isNotNull()) {
-				Structure targetStructure = pTar.fetchData(blenderContext.getInputStream()).get(0);
-				Long targetOMA = pTar.getOldMemoryAddress();
-				Space targetSpace = Space.valueOf(((Number) constraintStructure.getFieldValue("tarspace")).byteValue());
-				ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
-				Spatial target = (Spatial) objectHelper.toObject(targetStructure, blenderContext);
-				this.target = new Feature(target, targetSpace, targetOMA, blenderContext);
-			} else {
-				this.target = null;
+				this.targetOMA = pTar.getOldMemoryAddress();
+				this.targetSpace = Space.valueOf(((Number) constraintStructure.getFieldValue("tarspace")).byteValue());
+				subtargetName = data.getFieldValue("subtarget").toString();
 			}
 		} else {
-			throw new BlenderFileException("The constraint has no data specified!");
+			//Null constraint has no data, so create it here
+			constraintDefinition = ConstraintDefinitionFactory.createConstraintDefinition(null, blenderContext);
 		}
-		Space ownerSpace = Space.valueOf(((Number) constraintStructure.getFieldValue("ownspace")).byteValue());
-		this.owner = new Feature(ownerSpace, ownerOMA, blenderContext);
+		this.ownerSpace = Space.valueOf(((Number) constraintStructure.getFieldValue("ownspace")).byteValue());
 		this.ipo = influenceIpo;
+		this.ownerOMA = ownerOMA;
+		this.constraintHelper = blenderContext.getHelper(ConstraintHelper.class);
 	}
-
+	
 	/**
-	 * This method bakes the required sontraints into its owner.
+	 * This method bakes the required sontraints into its owner. It checks if the constraint is invalid
+	 * or if it isn't yet baked. It also performs baking of its target constraints so that the proper baking
+	 * order is kept.
 	 */
 	public void bake() {
-		this.owner.update();
-		if(this.target != null) {
-			this.target.update();
+		if(invalid) {
+			LOGGER.warning("The constraint " + name + " is invalid and will not be applied.");
+		} else if(!baked) {
+			if(targetOMA != null) {
+				List<Constraint> targetConstraints = blenderContext.getConstraints(targetOMA);
+				if(targetConstraints != null && targetConstraints.size() > 0) {
+					LOGGER.log(Level.FINE, "Baking target constraints of constraint: {0}", name);
+					for(Constraint targetConstraint : targetConstraints) {
+						targetConstraint.bake();
+					}
+				}
+			}
+			
+			LOGGER.log(Level.FINE, "Performing baking of constraint: {0}", name);
+			this.performBakingOperation();
+			baked = true;
 		}
-		this.bakeConstraint();
 	}
 	
 	/**
-	 * Bake the animation's constraints into its owner.
+	 * This method should be overwridden and perform the baking opertion.
 	 */
-	protected abstract void bakeConstraint();
+	protected abstract void performBakingOperation();
 	
-    /**
-     * This method returns the bone traces for the bone that is affected by the given constraint.
-     * @param skeleton
-     *        the skeleton containing bones
-     * @param boneAnimation
-     *        the bone animation that affects the skeleton
-     * @return the bone track for the bone that is being affected by the constraint
-     */
-    protected BlenderTrack getTrack(Object owner, Skeleton skeleton, Animation animation) {
-    	if(owner instanceof Bone) {
-    		int boneIndex = skeleton.getBoneIndex((Bone) owner);
-    		for (Track track : animation.getTracks()) {
-                if (((BoneTrack) track).getTargetBoneIndex() == boneIndex) {
-                    return new BlenderTrack(((BoneTrack) track));
-                }
-            }
-    		throw new IllegalStateException("Cannot find track for: " + owner);
-    	} else {
-    		return new BlenderTrack((SpatialTrack)animation.getTracks()[0]);
-    	}
-    }
-    
 	/**
-	 * The space of target or owner transformation.
-	 * 
-	 * @author Marcin Roguski (Kaelthas)
+	 * This method prepares the tracks for both owner and parent. If either owner or parent have no track while its parent has - 
+	 * the tracks are created. The tracks will not modify the owner/target movement but will be there ready for applying constraints.
+	 * For example if the owner is a spatial and has no animation but its parent is moving then the track is created for the owner
+	 * that will have non modifying values for translation, rotation and scale and will have the same amount of frames as its parent has.
 	 */
-	public static enum Space {
-
-		CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_PARLOCAL, CONSTRAINT_SPACE_INVALID;
-
-		/**
-		 * This method returns the enum instance when given the appropriate
-		 * value from the blend file.
-		 * 
-		 * @param c
-		 *            the blender's value of the space modifier
-		 * @return the scape enum instance
-		 */
-		public static Space valueOf(byte c) {
-			switch (c) {
-				case 0:
-					return CONSTRAINT_SPACE_WORLD;
-				case 1:
-					return CONSTRAINT_SPACE_LOCAL;
-				case 2:
-					return CONSTRAINT_SPACE_POSE;
-				case 3:
-					return CONSTRAINT_SPACE_PARLOCAL;
-				default:
-					return CONSTRAINT_SPACE_INVALID;
-			}
-		}
-	}
+	protected abstract void prepareTracksForApplyingConstraints();
 }

+ 0 - 42
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintAction.java

@@ -1,42 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * This class represents 'Action' constraint type in blender.
- * @author Marcin Roguski (Kaelthas)
- */
-/*package*/ class ConstraintAction extends Constraint {
-	private static final Logger LOGGER = Logger.getLogger(ConstraintAction.class.getName());
-	
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintAction(Structure constraintStructure, Long ownerOMA,
-			Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-	}
-	
-	@Override
-	protected void bakeConstraint() {
-		// TODO: implement 'Action' constraint
-		LOGGER.log(Level.WARNING, "'Action' constraint NOT implemented!");
-	}
-}

+ 0 - 42
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintChildOf.java

@@ -1,42 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * This class represents 'ChildOf' constraint type in blender.
- * @author Marcin Roguski (Kaelthas)
- */
-/*package*/ class ConstraintChildOf extends Constraint {
-	private static final Logger LOGGER = Logger.getLogger(ConstraintChildOf.class.getName());
-	
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintChildOf(Structure constraintStructure, Long ownerOMA,
-			Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-	}
-
-	@Override
-	protected void bakeConstraint() {
-		// TODO: implement ChildOf constraint
-		LOGGER.log(Level.WARNING, "ChildOf constraint NOT implemented!");
-	}
-}

+ 0 - 43
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintClampTo.java

@@ -1,43 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * This class represents 'Clamp to' constraint type in blender.
- * @author Marcin Roguski (Kaelthas)
- */
-/*package*/ class ConstraintClampTo extends Constraint {
-	private static final Logger LOGGER = Logger.getLogger(ConstraintClampTo.class.getName());
-	
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintClampTo(Structure constraintStructure, Long ownerOMA,
-			Ipo influenceIpo, BlenderContext blenderContext)
-			throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-	}
-
-	@Override
-	protected void bakeConstraint() {
-		//TODO: implement when curves are implemented
-		LOGGER.log(Level.INFO, "'Clamp to' not yet implemented! Curves not yet implemented!", name);
-	}
-}

+ 0 - 42
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintDampTrack.java

@@ -1,42 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * The damp track constraint. Available for blender 2.50+.
- * @author Marcin Roguski (Kaelthas)
- */
-/*package*/ class ConstraintDampTrack extends Constraint {
-	private static final Logger LOGGER = Logger.getLogger(ConstraintDampTrack.class.getName());
-	
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintDampTrack(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-		// TODO Auto-generated constructor stub
-	}
-
-	@Override
-	protected void bakeConstraint() {
-		// TODO Auto-generated method stub
-		LOGGER.log(Level.WARNING, "'Damp Track' constraint NOT implemented!");
-	}
-}

+ 0 - 120
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintDistLimit.java

@@ -1,120 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import com.jme3.animation.Animation;
-import com.jme3.math.Matrix4f;
-import com.jme3.math.Vector3f;
-import com.jme3.scene.Spatial;
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-import com.jme3.scene.plugins.ogre.AnimData;
-
-/**
- * This class represents 'Dist limit' constraint type in blender.
- * @author Marcin Roguski (Kaelthas)
- */
-/*package*/ class ConstraintDistLimit extends Constraint {
-	private static final int LIMITDIST_INSIDE = 0;
-	private static final int LIMITDIST_OUTSIDE = 1;
-	private static final int LIMITDIST_ONSURFACE = 2;
-    
-	protected int mode;
-	protected float dist;
-	
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintDistLimit(Structure constraintStructure, Long ownerOMA,
-			Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-		
-		mode = ((Number) data.getFieldValue("mode")).intValue();
-		dist = ((Number) data.getFieldValue("dist")).floatValue();
-	}
-
-	@Override
-	protected void bakeConstraint() {
-		Object owner = this.owner.getObject();
-		AnimData animData = blenderContext.getAnimData(this.owner.getOma());
-		if(animData != null) {
-			if(owner instanceof Spatial) {
-				Vector3f targetLocation = ((Spatial) owner).getWorldTranslation();
-				for(Animation animation : animData.anims) {
-					BlenderTrack blenderTrack = this.getTrack(owner, animData.skeleton, animation);
-					int maxFrames = blenderTrack.getTimes().length;
-					Vector3f[] translations = blenderTrack.getTranslations();
-					for (int frame = 0; frame < maxFrames; ++frame) {
-						Vector3f v = translations[frame].subtract(targetLocation);
-						this.distLimit(v, targetLocation, ipo.calculateValue(frame));
-						translations[frame].addLocal(v);
-					}
-					blenderTrack.setKeyframes(blenderTrack.getTimes(), translations, blenderTrack.getRotations(), blenderTrack.getScales());
-				}
-			}
-		}
-		
-		// apply static constraint only to spatials
-		if(owner instanceof Spatial) {
-			Matrix4f targetWorldMatrix = target.getWorldTransformMatrix();
-			Vector3f targetLocation = targetWorldMatrix.toTranslationVector();
-			Matrix4f m = this.owner.getParentWorldTransformMatrix();
-			m.invertLocal();
-			Matrix4f ownerWorldMatrix = this.owner.getWorldTransformMatrix();
-			Vector3f ownerLocation = ownerWorldMatrix.toTranslationVector();
-			this.distLimit(ownerLocation, targetLocation, ipo.calculateValue(0));
-			((Spatial) owner).setLocalTranslation(m.mult(ownerLocation));
-		}
-	}
-	
-	/**
-	 * 
-	 * @param currentLocation
-	 * @param targetLocation
-	 * @param influence
-	 */
-	private void distLimit(Vector3f currentLocation, Vector3f targetLocation, float influence) {
-		Vector3f v = currentLocation.subtract(targetLocation);
-		float currentDistance = v.length();
-		
-		switch (mode) {
-			case LIMITDIST_INSIDE:
-				if (currentDistance >= dist) {
-					v.normalizeLocal();
-					v.multLocal(dist + (currentDistance - dist) * (1.0f - influence));
-					currentLocation.set(v.addLocal(targetLocation));
-				}
-				break;
-			case LIMITDIST_ONSURFACE:
-				if (currentDistance > dist) {
-					v.normalizeLocal();
-					v.multLocal(dist + (currentDistance - dist) * (1.0f - influence));
-					currentLocation.set(v.addLocal(targetLocation));
-				} else if(currentDistance < dist) {
-					v.normalizeLocal().multLocal(dist * influence);
-					currentLocation.set(targetLocation.add(v));
-				}
-				break;
-			case LIMITDIST_OUTSIDE:
-				if (currentDistance <= dist) {
-					v = targetLocation.subtract(currentLocation).normalizeLocal().multLocal(dist * influence);
-					currentLocation.set(targetLocation.add(v));
-				}
-				break;
-			default:
-				throw new IllegalStateException("Unknown distance limit constraint mode: " + mode);
-		}
-	}
-}

+ 0 - 42
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintFollowPath.java

@@ -1,42 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * This class represents 'Follow path' constraint type in blender.
- * @author Marcin Roguski (Kaelthas)
- */
-/*package*/ class ConstraintFollowPath extends Constraint {
-	private static final Logger LOGGER = Logger.getLogger(ConstraintFollowPath.class.getName());
-	
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintFollowPath(Structure constraintStructure, Long ownerOMA,
-			Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-	}
-
-	@Override
-	protected void bakeConstraint() {
-		//TODO: implement when curves are implemented
-		LOGGER.log(Level.INFO, "'Follow path' not implemented! Curves not yet implemented!");
-	}
-}

+ 353 - 84
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintHelper.java

@@ -1,18 +1,31 @@
 package com.jme3.scene.plugins.blender.constraints;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import com.jme3.animation.Animation;
+import com.jme3.animation.Bone;
+import com.jme3.animation.BoneTrack;
+import com.jme3.animation.Skeleton;
+import com.jme3.animation.SpatialTrack;
+import com.jme3.animation.Track;
+import com.jme3.math.Matrix4f;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Transform;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.Spatial;
 import com.jme3.scene.plugins.blender.AbstractBlenderHelper;
 import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.BlenderContext.LoadedFeatureDataType;
 import com.jme3.scene.plugins.blender.animations.Ipo;
 import com.jme3.scene.plugins.blender.animations.IpoHelper;
 import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
+import com.jme3.scene.plugins.blender.file.DynamicArray;
 import com.jme3.scene.plugins.blender.file.Pointer;
 import com.jme3.scene.plugins.blender.file.Structure;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Logger;
 
 /**
  * This class should be used for constraint calculations.
@@ -21,38 +34,6 @@ import java.util.logging.Logger;
 public class ConstraintHelper extends AbstractBlenderHelper {
 	private static final Logger LOGGER = Logger.getLogger(ConstraintHelper.class.getName());
 	
-	private static final Map<String, Class<? extends Constraint>> constraintClasses = new HashMap<String, Class<? extends Constraint>>(22);
-	static {
-		constraintClasses.put("bActionConstraint", ConstraintAction.class);
-		constraintClasses.put("bChildOfConstraint", ConstraintChildOf.class);
-		constraintClasses.put("bClampToConstraint", ConstraintClampTo.class);
-		constraintClasses.put("bDistLimitConstraint", ConstraintDistLimit.class);
-		constraintClasses.put("bFollowPathConstraint", ConstraintFollowPath.class);
-		constraintClasses.put("bKinematicConstraint", ConstraintInverseKinematics.class);
-		constraintClasses.put("bLockTrackConstraint", ConstraintLockTrack.class);
-		constraintClasses.put("bLocateLikeConstraint", ConstraintLocLike.class);
-		constraintClasses.put("bLocLimitConstraint", ConstraintLocLimit.class);
-		constraintClasses.put("bMinMaxConstraint", ConstraintMinMax.class);
-		constraintClasses.put("bNullConstraint", ConstraintNull.class);
-		constraintClasses.put("bPythonConstraint", ConstraintPython.class);
-		constraintClasses.put("bRigidBodyJointConstraint", ConstraintRigidBodyJoint.class);
-		constraintClasses.put("bRotateLikeConstraint", ConstraintRotLike.class);
-		constraintClasses.put("bShrinkWrapConstraint", ConstraintShrinkWrap.class);
-		constraintClasses.put("bSizeLikeConstraint", ConstraintSizeLike.class);
-		constraintClasses.put("bSizeLimitConstraint", ConstraintSizeLimit.class);
-		constraintClasses.put("bStretchToConstraint", ConstraintStretchTo.class);
-		constraintClasses.put("bTransformConstraint", ConstraintTransform.class);
-		constraintClasses.put("bRotLimitConstraint", ConstraintRotLimit.class);
-		//Blender 2.50+
-		constraintClasses.put("bSplineIKConstraint", ConstraintSplineInverseKinematic.class);
-		constraintClasses.put("bDampTrackConstraint", ConstraintDampTrack.class);
-		constraintClasses.put("bPivotConstraint", ConstraintDampTrack.class);
-		//Blender 2.56+
-		constraintClasses.put("bTrackToConstraint", ConstraintTrackTo.class);
-		constraintClasses.put("bSameVolumeConstraint", ConstraintSameVolume.class);
-		constraintClasses.put("bTransLikeConstraint", ConstraintTransLike.class);
-	}
-	
 	/**
 	 * Helper constructor. It's main task is to generate the affection functions. These functions are common to all
 	 * ConstraintHelper instances. Unfortunately this constructor might grow large. If it becomes too large - I shall
@@ -125,7 +106,7 @@ public class ConstraintHelper extends AbstractBlenderHelper {
 						float enforce = ((Number) constraint.getFieldValue("enforce")).floatValue();
 						ipo = ipoHelper.fromValue(enforce);
 					}
-					constraintsList.add(this.createConstraint(constraint, boneOMA, ipo, blenderContext));
+					constraintsList.add(new BoneConstraint(constraint, boneOMA, ipo, blenderContext));
 				}
 				blenderContext.addConstraints(boneOMA, constraintsList);
 			}
@@ -133,74 +114,362 @@ public class ConstraintHelper extends AbstractBlenderHelper {
 
 		//loading constraints connected with the object itself
 		List<Structure> constraints = ((Structure)objectStructure.getFieldValue("constraints")).evaluateListBase(blenderContext);
-		List<Constraint> constraintsList = new ArrayList<Constraint>(constraints.size());
-		
-		for(Structure constraint : constraints) {
-			String constraintName = constraint.getFieldValue("name").toString();
-			String objectName = objectStructure.getName();
+		if(constraints != null && constraints.size() > 0) {
+			Pointer pData = (Pointer) objectStructure.getFieldValue("data");
+			String dataType = pData.isNotNull() ? pData.fetchData(blenderContext.getInputStream()).get(0).getType() : null;
+			List<Constraint> constraintsList = new ArrayList<Constraint>(constraints.size());
 			
-			Map<String, Ipo> objectConstraintsIpos = constraintsIpos.get(objectName);
-			Ipo ipo = objectConstraintsIpos!=null ? objectConstraintsIpos.get(constraintName) : null;
-			if (ipo == null) {
-				float enforce = ((Number) constraint.getFieldValue("enforce")).floatValue();
-				ipo = ipoHelper.fromValue(enforce);
+			for(Structure constraint : constraints) {
+				String constraintName = constraint.getFieldValue("name").toString();
+				String objectName = objectStructure.getName();
+				
+				Map<String, Ipo> objectConstraintsIpos = constraintsIpos.get(objectName);
+				Ipo ipo = objectConstraintsIpos!=null ? objectConstraintsIpos.get(constraintName) : null;
+				if (ipo == null) {
+					float enforce = ((Number) constraint.getFieldValue("enforce")).floatValue();
+					ipo = ipoHelper.fromValue(enforce);
+				}
+				
+				constraintsList.add(this.getConstraint(dataType, constraint, objectStructure.getOldMemoryAddress(), ipo, blenderContext));
 			}
-			constraintsList.add(this.createConstraint(constraint, objectStructure.getOldMemoryAddress(), ipo, blenderContext));
+			blenderContext.addConstraints(objectStructure.getOldMemoryAddress(), constraintsList);
 		}
-		blenderContext.addConstraints(objectStructure.getOldMemoryAddress(), constraintsList);
 	}
 	
 	/**
-	 * This method creates the constraint instance.
+	 * This method creates a proper constraint object depending on the object's
+	 * data type. Supported data types: <li>Mesh <li>Armature <li>Camera <li>
+	 * Lamp Bone constraints are created in a different place.
 	 * 
+	 * @param dataType
+	 *            the type of the object's data
 	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
+	 *            the constraint structure
 	 * @param ownerOMA
-	 *            the old memory address of the constraint's owner
+	 *            the owner OMA
 	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
+	 *            the influence interpolation curve
 	 * @param blenderContext
 	 *            the blender context
+	 * @return constraint object for the required type
 	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
+	 *             thrown when problems with blender file occured
 	 */
-	protected Constraint createConstraint(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, 
-						BlenderContext blenderContext) throws BlenderFileException {
-		String constraintClassName = this.getConstraintClassName(constraintStructure, blenderContext);
-		Class<? extends Constraint> constraintClass = constraintClasses.get(constraintClassName);
-		if(constraintClass != null) {
-			try {
-				return (Constraint) constraintClass.getDeclaredConstructors()[0].newInstance(constraintStructure, ownerOMA, influenceIpo, 
-						blenderContext);
-			} catch (IllegalArgumentException e) {
-				throw new BlenderFileException(e.getLocalizedMessage(), e);
-			} catch (SecurityException e) {
-				throw new BlenderFileException(e.getLocalizedMessage(), e);
-			} catch (InstantiationException e) {
-				throw new BlenderFileException(e.getLocalizedMessage(), e);
-			} catch (IllegalAccessException e) {
-				throw new BlenderFileException(e.getLocalizedMessage(), e);
-			} catch (InvocationTargetException e) {
-				throw new BlenderFileException(e.getLocalizedMessage(), e);
-			}
+	private Constraint getConstraint(String dataType, Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
+		if(dataType == null || "Mesh".equalsIgnoreCase(dataType) || "Camera".equalsIgnoreCase(dataType) || "Lamp".equalsIgnoreCase(dataType)) {
+			return new SpatialConstraint(constraintStructure, ownerOMA, influenceIpo, blenderContext);
+		} else if("Armature".equalsIgnoreCase(dataType)) {
+			return new SkeletonConstraint(constraintStructure, ownerOMA, influenceIpo, blenderContext);
 		} else {
-			throw new BlenderFileException("Unknown constraint type: " + constraintClassName);
+			throw new IllegalArgumentException("Unsupported data type for applying constraints: " + dataType);
 		}
 	}
 	
-	protected String getConstraintClassName(Structure constraintStructure, BlenderContext blenderContext) throws BlenderFileException {
-		Pointer pData = (Pointer)constraintStructure.getFieldValue("data");
-		if(pData.isNotNull()) {
-			Structure data = pData.fetchData(blenderContext.getInputStream()).get(0);
-			return data.getType();
-			
+	/**
+	 * The method bakes all available and valid constraints.
+	 * 
+	 * @param blenderContext
+	 *            the blender context
+	 */
+	public void bakeConstraints(BlenderContext blenderContext) {
+		for(Constraint constraint : blenderContext.getAllConstraints()) {
+			constraint.bake();
 		}
-		return constraintStructure.getType();
+	}
+	
+	/**
+	 * The method returns track for bone.
+	 * 
+	 * @param bone
+	 *            the bone
+	 * @param skeleton
+	 *            the bone's skeleton
+	 * @param animation
+	 *            the bone's animation
+	 * @return track for the given bone that was found among the given
+	 *         animations or null if none is found
+	 */
+	/*package*/ BoneTrack getTrack(Bone bone, Skeleton skeleton, Animation animation) {
+		int boneIndex = skeleton.getBoneIndex(bone);
+		for (Track track : animation.getTracks()) {
+            if (((BoneTrack) track).getTargetBoneIndex() == boneIndex) {
+                return (BoneTrack) track;
+            }
+        }
+		return null;
+	}
+	
+	/**
+	 * The method returns track for spatial.
+	 * 
+	 * @param bone
+	 *            the spatial
+	 * @param animation
+	 *            the spatial's animation
+	 * @return track for the given spatial that was found among the given
+	 *         animations or null if none is found
+	 */
+	/*package*/ SpatialTrack getTrack(Spatial spatial, Animation animation) {
+		Track[] tracks = animation.getTracks();
+		if(tracks != null && tracks.length == 1) {
+			return (SpatialTrack)tracks[0];
+		}
+		return null;
+	}
+	
+	/**
+	 * This method returns the transform read directly from the blender
+	 * structure. This can be used to read transforms from one of the object
+	 * types: <li>Spatial <li>Camera <li>Light
+	 * 
+	 * @param space
+	 *            the space where transform is evaluated
+	 * @param spatialOMA
+	 *            the OMA of the object
+	 * @param blenderContext
+	 *            the blender context
+	 * @return the object's transform in a given space
+	 */
+	@SuppressWarnings("unchecked")
+	/*package*/ Transform getNodeObjectTransform(Space space, Long spatialOMA, BlenderContext blenderContext) {
+		switch (space) {
+			case CONSTRAINT_SPACE_LOCAL:
+				Structure targetStructure = (Structure) blenderContext.getLoadedFeature(spatialOMA, LoadedFeatureDataType.LOADED_STRUCTURE);
+	
+				DynamicArray<Number> locArray = ((DynamicArray<Number>) targetStructure.getFieldValue("loc"));
+				Vector3f loc = new Vector3f(locArray.get(0).floatValue(), locArray.get(1).floatValue(), locArray.get(2).floatValue());
+				DynamicArray<Number> rotArray = ((DynamicArray<Number>) targetStructure.getFieldValue("rot"));
+				Quaternion rot = new Quaternion(new float[] { rotArray.get(0).floatValue(), rotArray.get(1).floatValue(), rotArray.get(2).floatValue() });
+				DynamicArray<Number> sizeArray = ((DynamicArray<Number>) targetStructure.getFieldValue("size"));
+				Vector3f size = new Vector3f(sizeArray.get(0).floatValue(), sizeArray.get(1).floatValue(), sizeArray.get(2).floatValue());
+	
+				if (blenderContext.getBlenderKey().isFixUpAxis()) {
+					float y = loc.y;
+					loc.y = loc.z;
+					loc.z = -y;
+	
+					y = rot.getY();
+					float z = rot.getZ();
+					rot.set(rot.getX(), z, -y, rot.getW());
+	
+					y = size.y;
+					size.y = size.z;
+					size.z = y;
+				}
+	
+				Transform result = new Transform(loc, rot);
+				result.setScale(size);
+				return result;
+			case CONSTRAINT_SPACE_WORLD://TODO: get it from the object structure ???
+				Object feature = blenderContext.getLoadedFeature(spatialOMA, LoadedFeatureDataType.LOADED_FEATURE);
+				if(feature instanceof Spatial) {
+					return ((Spatial) feature).getWorldTransform();
+				}  else if(feature instanceof Skeleton) {
+					LOGGER.warning("Trying to get transformation for skeleton. This is not supported. Returning null.");
+					return null;
+				} else {
+					throw new IllegalArgumentException("Given old memory address does not point to a valid object type (spatial, camera or light).");
+				}
+			default:
+				throw new IllegalStateException("Invalid space type for target object: " + space.toString());
+		}
+	}
+	
+	/**
+	 * The method returns the transform for the given bone computed in the given
+	 * space.
+	 * 
+	 * @param space
+	 *            the computation space
+	 * @param bone
+	 *            the bone we get the transform from
+	 * @return the transform of the given bone
+	 */
+	/*package*/ Transform getBoneTransform(Space space, Bone bone) {
+		switch (space) {
+			case CONSTRAINT_SPACE_LOCAL:
+				Transform localTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation());
+				localTransform.setScale(bone.getLocalScale());
+				return localTransform;
+			case CONSTRAINT_SPACE_WORLD:
+				Transform worldTransform = new Transform(bone.getWorldBindPosition(), bone.getWorldBindRotation());
+				worldTransform.setScale(bone.getWorldBindScale());
+				return worldTransform;
+			case CONSTRAINT_SPACE_POSE:
+				Transform poseTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation());
+				poseTransform.setScale(bone.getLocalScale());
+				return poseTransform;
+			case CONSTRAINT_SPACE_PARLOCAL:
+				Transform parentLocalTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation());
+				parentLocalTransform.setScale(bone.getLocalScale());
+				return parentLocalTransform;
+			default:
+				throw new IllegalStateException("Invalid space type for target object: " + space.toString());
+		}
+	}
+	
+	/**
+	 * The method applies the transform for the given spatial, computed in the
+	 * given space.
+	 * 
+	 * @param spatial
+	 *            the spatial we apply the transform for
+	 * @param space
+	 *            the computation space
+	 * @param transform
+	 *            the transform being applied
+	 */
+	/*package*/ void applyTransform(Spatial spatial, Space space, Transform transform) {
+		switch (space) {
+			case CONSTRAINT_SPACE_LOCAL:
+				Transform ownerLocalTransform = spatial.getLocalTransform();
+				ownerLocalTransform.getTranslation().addLocal(transform.getTranslation());
+				ownerLocalTransform.getRotation().multLocal(transform.getRotation());
+				ownerLocalTransform.getScale().multLocal(transform.getScale());
+				break;
+			case CONSTRAINT_SPACE_WORLD:
+				Matrix4f m = this.getParentWorldTransformMatrix(spatial);
+				m.invertLocal();
+				Matrix4f matrix = this.toMatrix(transform);
+				m.multLocal(matrix);
+	
+				float scaleX = (float) Math.sqrt(m.m00 * m.m00 + m.m10 * m.m10 + m.m20 * m.m20);
+				float scaleY = (float) Math.sqrt(m.m01 * m.m01 + m.m11 * m.m11 + m.m21 * m.m21);
+				float scaleZ = (float) Math.sqrt(m.m02 * m.m02 + m.m12 * m.m12 + m.m22 * m.m22);
+	
+				transform.setTranslation(m.toTranslationVector());
+				transform.setRotation(m.toRotationQuat());
+				transform.setScale(scaleX, scaleY, scaleZ);
+				spatial.setLocalTransform(transform);
+				break;
+			case CONSTRAINT_SPACE_PARLOCAL:
+			case CONSTRAINT_SPACE_POSE:
+				throw new IllegalStateException("Invalid space type (" + space.toString() + ") for owner object.");
+			default:
+				throw new IllegalStateException("Invalid space type for target object: " + space.toString());
+		}
+	}
+	
+	/**
+	 * The method applies the transform for the given bone, computed in the
+	 * given space.
+	 * 
+	 * @param bone
+	 *            the bone we apply the transform for
+	 * @param space
+	 *            the computation space
+	 * @param transform
+	 *            the transform being applied
+	 */
+	/*package*/ void applyTransform(Bone bone, Space space, Transform transform) {
+		switch (space) {
+			case CONSTRAINT_SPACE_LOCAL:
+				bone.setBindTransforms(transform.getTranslation(), transform.getRotation(), transform.getScale());
+				break;
+			case CONSTRAINT_SPACE_WORLD:
+				Matrix4f m = this.getParentWorldTransformMatrix(bone);
+		//			m.invertLocal();
+				transform.setTranslation(m.mult(transform.getTranslation()));
+				transform.setRotation(m.mult(transform.getRotation(), null));
+				transform.setScale(transform.getScale());
+				bone.setBindTransforms(transform.getTranslation(), transform.getRotation(), transform.getScale());
+		//			float x = FastMath.HALF_PI/2;
+		//			float y = -FastMath.HALF_PI;
+		//			float z = -FastMath.HALF_PI/2;
+		//			bone.setBindTransforms(new Vector3f(0,0,0), new Quaternion().fromAngles(x, y, z), new Vector3f(1,1,1));
+				break;
+			case CONSTRAINT_SPACE_PARLOCAL:
+				Vector3f parentLocalTranslation = bone.getLocalPosition().add(transform.getTranslation());
+				Quaternion parentLocalRotation = bone.getLocalRotation().mult(transform.getRotation());
+				bone.setBindTransforms(parentLocalTranslation, parentLocalRotation, transform.getScale());
+				break;
+			case CONSTRAINT_SPACE_POSE:
+				bone.setBindTransforms(transform.getTranslation(), transform.getRotation(), transform.getScale());
+				break;
+			default:
+				throw new IllegalStateException("Invalid space type for target object: " + space.toString());
+		}
+	}
+	
+	/**
+	 * @return world transform matrix of the feature's parent or identity matrix
+	 *         if the feature has no parent
+	 */
+	private Matrix4f getParentWorldTransformMatrix(Spatial spatial) {
+		Matrix4f result = new Matrix4f();
+		if (spatial.getParent() != null) {
+			Transform t = spatial.getParent().getWorldTransform();
+			result.setTransform(t.getTranslation(), t.getScale(), t.getRotation().toRotationMatrix());
+		}
+		return result;
+	}
+	
+	/**
+	 * @return world transform matrix of the feature's parent or identity matrix
+	 *         if the feature has no parent
+	 */
+	private Matrix4f getParentWorldTransformMatrix(Bone bone) {
+		Matrix4f result = new Matrix4f();
+		Bone parent = bone.getParent();
+		if (parent != null) {
+			result.setTransform(parent.getWorldBindPosition(), parent.getWorldBindScale(), parent.getWorldBindRotation().toRotationMatrix());
+		}
+		return result;
+	}
+
+	/**
+	 * Converts given transform to the matrix.
+	 * 
+	 * @param transform
+	 *            the transform to be converted
+	 * @return 4x4 matri that represents the given transform
+	 */
+	private Matrix4f toMatrix(Transform transform) {
+		Matrix4f result = Matrix4f.IDENTITY;
+		if (transform != null) {
+			result = new Matrix4f();
+			result.setTranslation(transform.getTranslation());
+			result.setRotationQuaternion(transform.getRotation());
+			result.setScale(transform.getScale());
+		}
+		return result;
 	}
 	
 	@Override
 	public boolean shouldBeLoaded(Structure structure, BlenderContext blenderContext) {
 		return true;
 	}
+	
+	/**
+	 * The space of target or owner transformation.
+	 * 
+	 * @author Marcin Roguski (Kaelthas)
+	 */
+	public static enum Space {
+
+		CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_PARLOCAL, CONSTRAINT_SPACE_INVALID;
+
+		/**
+		 * This method returns the enum instance when given the appropriate
+		 * value from the blend file.
+		 * 
+		 * @param c
+		 *            the blender's value of the space modifier
+		 * @return the scape enum instance
+		 */
+		public static Space valueOf(byte c) {
+			switch (c) {
+				case 0:
+					return CONSTRAINT_SPACE_WORLD;
+				case 1:
+					return CONSTRAINT_SPACE_LOCAL;
+				case 2:
+					return CONSTRAINT_SPACE_POSE;
+				case 3:
+					return CONSTRAINT_SPACE_PARLOCAL;
+				default:
+					return CONSTRAINT_SPACE_INVALID;
+			}
+		}
+	}
 }

+ 0 - 122
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLocLike.java

@@ -1,122 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import com.jme3.animation.Animation;
-import com.jme3.math.Transform;
-import com.jme3.math.Vector3f;
-import com.jme3.scene.Spatial;
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-import com.jme3.scene.plugins.ogre.AnimData;
-
-/**
- * This class represents 'Loc like' constraint type in blender.
- * @author Marcin Roguski (Kaelthas)
- */
-/*package*/ class ConstraintLocLike extends Constraint {
-	private static final int LOCLIKE_X = 0x01;
-	private static final int LOCLIKE_Y = 0x02;
-	private static final int LOCLIKE_Z = 0x04;
-    //protected static final int LOCLIKE_TIP = 0x08;//this is deprecated in blender
-    private static final int LOCLIKE_X_INVERT = 0x10;
-    private static final int LOCLIKE_Y_INVERT = 0x20;
-    private static final int LOCLIKE_Z_INVERT = 0x40;
-    private static final int LOCLIKE_OFFSET = 0x80;
-    
-    protected int flag;
-    
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintLocLike(Structure constraintStructure, Long ownerOMA,
-			Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-		
-		flag = ((Number) data.getFieldValue("flag")).intValue();
-		
-		if(blenderContext.getBlenderKey().isFixUpAxis()) {
-			//swapping Y and X limits flag in the bitwise flag
-			int y = flag & LOCLIKE_Y;
-			int invY = flag & LOCLIKE_Y_INVERT;
-			int z = flag & LOCLIKE_Z;
-			int invZ = flag & LOCLIKE_Z_INVERT;
-			flag &= LOCLIKE_X | LOCLIKE_X_INVERT | LOCLIKE_OFFSET;//clear the other flags to swap them
-			flag |= y << 2;
-			flag |= invY << 2;
-			flag |= z >> 2;
-			flag |= invZ >> 2;
-		}
-	}
-
-	@Override
-	protected void bakeConstraint() {
-		Object owner = this.owner.getObject();
-		AnimData animData = blenderContext.getAnimData(this.owner.getOma());
-		if(animData != null) {
-			Transform targetTransform = this.target.getTransform();
-			for(Animation animation : animData.anims) {
-				BlenderTrack blenderTrack = this.getTrack(owner, animData.skeleton, animation);
-				Vector3f[] translations = blenderTrack.getTranslations();
-				int maxFrames = translations.length;
-				for (int frame = 0; frame < maxFrames; ++frame) {
-					this.locLike(translations[frame], targetTransform.getTranslation(), ipo.calculateValue(frame));
-				}
-				blenderTrack.setKeyframes(blenderTrack.getTimes(), translations, blenderTrack.getRotations(), blenderTrack.getScales());
-			}
-		}
-		
-		if(owner instanceof Spatial) {
-			Transform targetTransform = this.target.getTransform();
-			Transform ownerTransform = this.owner.getTransform();
-			Vector3f ownerLocation = ownerTransform.getTranslation();
-			this.locLike(ownerLocation, targetTransform.getTranslation(), ipo.calculateValue(0));
-			this.owner.applyTransform(ownerTransform);
-		}
-	}
-	
-	private void locLike(Vector3f ownerLocation, Vector3f targetLocation, float influence) {
-		Vector3f startLocation = ownerLocation.clone();
-		Vector3f offset = Vector3f.ZERO;
-		if ((flag & LOCLIKE_OFFSET) != 0) {//we add the original location to the copied location
-			offset = startLocation;
-		}
-
-		if ((flag & LOCLIKE_X) != 0) {
-			ownerLocation.x = targetLocation.x;
-			if ((flag & LOCLIKE_X_INVERT) != 0) {
-				ownerLocation.x = -ownerLocation.x;
-			}
-		}
-		if ((flag & LOCLIKE_Y) != 0) {
-			ownerLocation.y = targetLocation.y;
-			if ((flag & LOCLIKE_Y_INVERT) != 0) {
-				ownerLocation.y = -ownerLocation.y;
-			}
-		}
-		if ((flag & LOCLIKE_Z) != 0) {
-			ownerLocation.z = targetLocation.z;
-			if ((flag & LOCLIKE_Z_INVERT) != 0) {
-				ownerLocation.z = -ownerLocation.z;
-			}
-		}
-		ownerLocation.addLocal(offset);
-		
-		if(influence < 1.0f) {
-			startLocation.subtractLocal(ownerLocation).normalizeLocal().mult(influence);
-			ownerLocation.addLocal(startLocation);
-		}
-	}
-}

+ 0 - 137
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLocLimit.java

@@ -1,137 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import com.jme3.animation.Animation;
-import com.jme3.math.Transform;
-import com.jme3.math.Vector3f;
-import com.jme3.scene.Spatial;
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-import com.jme3.scene.plugins.ogre.AnimData;
-
-/**
- * This class represents 'Loc limit' constraint type in blender.
- * @author Marcin Roguski (Kaelthas)
- */
-/*package*/ class ConstraintLocLimit extends Constraint {
-    private static final int LIMIT_XMIN = 0x01;
-    private static final int LIMIT_XMAX = 0x02;
-    private static final int LIMIT_YMIN = 0x04;
-    private static final int LIMIT_YMAX = 0x08;
-    private static final int LIMIT_ZMIN = 0x10;
-    private static final int LIMIT_ZMAX = 0x20;
-    
-    protected float[][] limits = new float[3][2];
-    protected int flag;
-    
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintLocLimit(Structure constraintStructure, Long ownerOMA,
-			Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-		
-		flag = ((Number) data.getFieldValue("flag")).intValue();
-		if(blenderContext.getBlenderKey().isFixUpAxis()) {
-			limits[0][0] = ((Number) data.getFieldValue("xmin")).floatValue();
-			limits[0][1] = ((Number) data.getFieldValue("xmax")).floatValue();
-			limits[2][0] = -((Number) data.getFieldValue("ymin")).floatValue();
-			limits[2][1] = -((Number) data.getFieldValue("ymax")).floatValue();
-			limits[1][0] = ((Number) data.getFieldValue("zmin")).floatValue();
-			limits[1][1] = ((Number) data.getFieldValue("zmax")).floatValue();
-			
-			//swapping Y and X limits flag in the bitwise flag
-			int ymin = flag & LIMIT_YMIN;
-			int ymax = flag & LIMIT_YMAX;
-			int zmin = flag & LIMIT_ZMIN;
-			int zmax = flag & LIMIT_ZMAX;
-			flag &= LIMIT_XMIN | LIMIT_XMAX;//clear the other flags to swap them
-			flag |= ymin << 2;
-			flag |= ymax << 2;
-			flag |= zmin >> 2;
-			flag |= zmax >> 2;
-		} else {
-			limits[0][0] = ((Number) data.getFieldValue("xmin")).floatValue();
-			limits[0][1] = ((Number) data.getFieldValue("xmax")).floatValue();
-			limits[1][0] = ((Number) data.getFieldValue("ymin")).floatValue();
-			limits[1][1] = ((Number) data.getFieldValue("ymax")).floatValue();
-			limits[2][0] = ((Number) data.getFieldValue("zmin")).floatValue();
-			limits[2][1] = ((Number) data.getFieldValue("zmax")).floatValue();
-		}
-	}
-
-	@Override
-	protected void bakeConstraint() {
-		Object owner = this.owner.getObject();
-		AnimData animData = blenderContext.getAnimData(this.owner.getOma());
-		if(animData != null) {
-			for(Animation animation : animData.anims) {
-				BlenderTrack track = this.getTrack(owner, animData.skeleton, animation);
-				Vector3f[] translations = track.getTranslations();
-				int maxFrames = translations.length;
-				for (int frame = 0; frame < maxFrames; ++frame) {
-					this.locLimit(translations[frame], ipo.calculateValue(frame));
-				}
-				track.setKeyframes(track.getTimes(), translations, track.getRotations(), track.getScales());
-			}
-		}
-		
-		if(owner instanceof Spatial) {
-			Transform ownerTransform = this.owner.getTransform();
-			Vector3f ownerLocation = ownerTransform.getTranslation();
-			this.locLimit(ownerLocation, ipo.calculateValue(0));
-			this.owner.applyTransform(ownerTransform);
-		}
-	}
-	
-	/**
-	 * This method modifies the given translation.
-	 * @param translation the translation to be modified.
-	 * @param influence the influence value
-	 */
-	private void locLimit(Vector3f translation, float influence) {
-		if ((flag & LIMIT_XMIN) != 0) {
-			if (translation.x < limits[0][0]) {
-				translation.x -= (translation.x - limits[0][0]) * influence;
-			}
-		}
-		if ((flag & LIMIT_XMAX) != 0) {
-			if (translation.x > limits[0][1]) {
-				translation.x -= (translation.x - limits[0][1]) * influence;
-			}
-		}
-		if ((flag & LIMIT_YMIN) != 0) {
-			if (translation.y < limits[1][0]) {
-				translation.y -= (translation.y - limits[1][0]) * influence;
-			}
-		}
-		if ((flag & LIMIT_YMAX) != 0) {
-			if (translation.y > limits[1][1]) {
-				translation.y -= (translation.y - limits[1][1]) * influence;
-			}
-		}
-		if ((flag & LIMIT_ZMIN) != 0) {
-			if (translation.z < limits[2][0]) {
-				translation.z -= (translation.z - limits[2][0]) * influence;
-			}
-		}
-		if ((flag & LIMIT_ZMAX) != 0) {
-			if (translation.z > limits[2][1]) {
-				translation.z -= (translation.z - limits[2][1]) * influence;
-			}
-		}
-	}
-}

+ 0 - 43
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLockTrack.java

@@ -1,43 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * This class represents 'Action' constraint type in blender.
- * @author Marcin Roguski (Kaelthas)
- */
-/*package*/ class ConstraintLockTrack extends Constraint {
-	private static final Logger LOGGER = Logger.getLogger(ConstraintLockTrack.class.getName());
-	
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintLockTrack(Structure constraintStructure, Long ownerOMA,
-			Ipo influenceIpo, BlenderContext blenderContext)
-			throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-	}
-
-	@Override
-	protected void bakeConstraint() {
-		// TODO: implement 'Lock track' constraint
-		LOGGER.log(Level.WARNING, "'Lock track' constraint NOT implemented!");
-	}
-}

+ 0 - 42
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintMinMax.java

@@ -1,42 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * This class represents 'Min max' constraint type in blender.
- * @author Marcin Roguski (Kaelthas)
- */
-/*package*/ class ConstraintMinMax extends Constraint {
-	private static final Logger LOGGER = Logger.getLogger(ConstraintMinMax.class.getName());
-	
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintMinMax(Structure constraintStructure, Long ownerOMA,
-			Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-	}
-
-	@Override
-	protected void bakeConstraint() {
-		// TODO: implement 'Min max' constraint
-		LOGGER.log(Level.WARNING, "'Min max' constraint NOT implemented!");
-	}
-}

+ 0 - 37
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintNull.java

@@ -1,37 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-
-/**
- * This class represents 'Null' constraint type in blender.
- * @author Marcin Roguski (Kaelthas)
- */
-/*package*/ class ConstraintNull extends Constraint {
-	
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintNull(Structure constraintStructure, Long ownerOMA,
-			Ipo influenceIpo, BlenderContext blenderContext)
-			throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-	}
-
-	@Override
-	protected void bakeConstraint() {}
-}

+ 0 - 43
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintPivot.java

@@ -1,43 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * The pivot constraint. Available for blender 2.50+.
- * @author Marcin Roguski (Kaelthas)
- */
-/*package*/ class ConstraintPivot extends Constraint {
-	private static final Logger LOGGER = Logger.getLogger(ConstraintPivot.class.getName());
-	
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintPivot(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo,
-			BlenderContext blenderContext) throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-		// TODO Auto-generated constructor stub
-	}
-
-	@Override
-	protected void bakeConstraint() {
-		// TODO Auto-generated method stub
-		LOGGER.log(Level.WARNING, "'Pivot' constraint NOT implemented!");
-	}
-}

+ 0 - 42
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintPython.java

@@ -1,42 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * This class represents 'Python' constraint type in blender.
- * @author Marcin Roguski (Kaelthas)
- */
-/*package*/ class ConstraintPython extends Constraint {
-	private static final Logger LOGGER = Logger.getLogger(ConstraintPython.class.getName());
-	
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintPython(Structure constraintStructure, Long ownerOMA,
-			Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-	}
-
-	@Override
-	protected void bakeConstraint() {
-		// TODO: implement 'Python' constraint
-		LOGGER.log(Level.WARNING, "'Python' constraint NOT implemented!");
-	}
-}

+ 0 - 42
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRigidBodyJoint.java

@@ -1,42 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * This class represents 'Rigid body joint' constraint type in blender.
- * @author Marcin Roguski (Kaelthas)
- */
-/*package*/ class ConstraintRigidBodyJoint extends Constraint {
-	private static final Logger LOGGER = Logger.getLogger(ConstraintRigidBodyJoint.class.getName());
-	
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintRigidBodyJoint(Structure constraintStructure,
-			Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-	}
-
-	@Override
-	protected void bakeConstraint() {
-		// TODO: implement 'Rigid body joint' constraint
-		LOGGER.log(Level.WARNING, "'Rigid body joint' constraint NOT implemented!");
-	}
-}

+ 0 - 114
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRotLike.java

@@ -1,114 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import com.jme3.animation.Animation;
-import com.jme3.math.Quaternion;
-import com.jme3.math.Transform;
-import com.jme3.scene.Spatial;
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-import com.jme3.scene.plugins.ogre.AnimData;
-
-/**
- * This class represents 'Rot like' constraint type in blender.
- * @author Marcin Roguski (Kaelthas)
- */
-/*package*/ class ConstraintRotLike extends Constraint {
-	private static final int ROTLIKE_X = 0x01;
-	private static final int ROTLIKE_Y = 0x02;
-	private static final int ROTLIKE_Z = 0x04;
-	private static final int ROTLIKE_X_INVERT = 0x10;
-    private static final int ROTLIKE_Y_INVERT = 0x20;
-    private static final int ROTLIKE_Z_INVERT = 0x40;
-    private static final int ROTLIKE_OFFSET = 0x80;
-    
-    protected int flag;
-    
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintRotLike(Structure constraintStructure, Long ownerOMA,
-			Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-		
-		flag = ((Number) data.getFieldValue("flag")).intValue();
-	}
-
-	@Override
-	protected void bakeConstraint() {
-		Object owner = this.owner.getObject();
-		AnimData animData = blenderContext.getAnimData(this.owner.getOma());
-		if(animData != null) {
-			Transform targetTransform = this.target.getTransform();
-			Quaternion targetRotation = targetTransform.getRotation();
-			for(Animation animation : animData.anims) {
-				BlenderTrack track = this.getTrack(owner, animData.skeleton, animation);
-				float[] targetAngles = targetRotation.toAngles(null);
-				Quaternion[] rotations = track.getRotations();
-				int maxFrames = rotations.length;
-				float[] angles = new float[3];
-				for (int frame = 0; frame < maxFrames; ++frame) {
-					rotations[frame].toAngles(angles);
-					this.rotLike(rotations[frame], angles, targetAngles, ipo.calculateValue(frame));
-				}
-				track.setKeyframes(track.getTimes(), track.getTranslations(), rotations, track.getScales());
-			}
-		}
-		
-		if(owner instanceof Spatial) {
-			Transform targetTransform = this.target.getTransform();
-			Transform ownerTransform = this.owner.getTransform();
-			Quaternion ownerRotation = ownerTransform.getRotation();
-			this.rotLike(ownerRotation, ownerRotation.toAngles(null), targetTransform.getRotation().toAngles(null), ipo.calculateValue(0));
-			this.owner.applyTransform(ownerTransform);
-		}
-	}
-	
-	private void rotLike(Quaternion ownerRotation, float[] ownerAngles, float[] targetAngles, float influence) {
-		Quaternion startRotation = ownerRotation.clone();
-		Quaternion offset = Quaternion.IDENTITY;
-		if ((flag & ROTLIKE_OFFSET) != 0) {//we add the original rotation to the copied rotation
-			offset = startRotation;
-		}
-
-		if ((flag & ROTLIKE_X) != 0) {
-			ownerAngles[0] = targetAngles[0];
-			if ((flag & ROTLIKE_X_INVERT) != 0) {
-				ownerAngles[0] = -ownerAngles[0];
-			}
-		}
-		if ((flag & ROTLIKE_Y) != 0) {
-			ownerAngles[1] = targetAngles[1];
-			if ((flag & ROTLIKE_Y_INVERT) != 0) {
-				ownerAngles[1] = -ownerAngles[1];
-			}
-		}
-		if ((flag & ROTLIKE_Z) != 0) {
-			ownerAngles[2] = targetAngles[2];
-			if ((flag & ROTLIKE_Z_INVERT) != 0) {
-				ownerAngles[2] = -ownerAngles[2];
-			}
-		}
-		ownerRotation.fromAngles(ownerAngles).multLocal(offset);
-
-		if(influence < 1.0f) {
-			
-//			startLocation.subtractLocal(ownerLocation).normalizeLocal().mult(influence);
-//			ownerLocation.addLocal(startLocation);
-			//TODO
-		}
-	}
-}

+ 0 - 180
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRotLimit.java

@@ -1,180 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import com.jme3.animation.Animation;
-import com.jme3.animation.Bone;
-import com.jme3.math.FastMath;
-import com.jme3.math.Quaternion;
-import com.jme3.math.Transform;
-import com.jme3.scene.Spatial;
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-import com.jme3.scene.plugins.ogre.AnimData;
-
-/**
- * This class represents 'Rot limit' constraint type in blender.
- * 
- * @author Marcin Roguski (Kaelthas)
- */
-/* package */class ConstraintRotLimit extends Constraint {
-	private static final int	LIMIT_XROT	= 0x01;
-	private static final int	LIMIT_YROT	= 0x02;
-	private static final int	LIMIT_ZROT	= 0x04;
-
-	protected float[][]			limits		= new float[3][2];
-	protected int				flag;
-	protected boolean			updated;
-
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintRotLimit(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-
-		flag = ((Number) data.getFieldValue("flag")).intValue();
-		if (blenderContext.getBlenderKey().isFixUpAxis() && owner.spatial != null) {
-			limits[0][0] = ((Number) data.getFieldValue("xmin")).floatValue();
-			limits[0][1] = ((Number) data.getFieldValue("xmax")).floatValue();
-			limits[2][0] = -((Number) data.getFieldValue("ymin")).floatValue();
-			limits[2][1] = -((Number) data.getFieldValue("ymax")).floatValue();
-			limits[1][0] = ((Number) data.getFieldValue("zmin")).floatValue();
-			limits[1][1] = ((Number) data.getFieldValue("zmax")).floatValue();
-
-			// swapping Y and X limits flag in the bitwise flag
-			int limitY = flag & LIMIT_YROT;
-			int limitZ = flag & LIMIT_ZROT;
-			flag &= LIMIT_XROT;// clear the other flags to swap them
-			flag |= limitY << 1;
-			flag |= limitZ >> 1;
-		} else {
-			limits[0][0] = ((Number) data.getFieldValue("xmin")).floatValue();
-			limits[0][1] = ((Number) data.getFieldValue("xmax")).floatValue();
-			limits[1][0] = ((Number) data.getFieldValue("ymin")).floatValue();
-			limits[1][1] = ((Number) data.getFieldValue("ymax")).floatValue();
-			limits[2][0] = ((Number) data.getFieldValue("zmin")).floatValue();
-			limits[2][1] = ((Number) data.getFieldValue("zmax")).floatValue();
-		}
-
-		// until blender 2.49 the rotations values were stored in degrees
-		if (blenderContext.getBlenderVersion() <= 249) {
-			for (int i = 0; i < limits.length; ++i) {
-				limits[i][0] *= FastMath.DEG_TO_RAD;
-				limits[i][1] *= FastMath.DEG_TO_RAD;
-			}
-		}
-	}
-
-	@Override
-	protected void bakeConstraint() {
-		this.update();
-		Object owner = this.owner.getObject();
-		AnimData animData = blenderContext.getAnimData(this.owner.getOma());
-		if (animData != null) {
-			for (Animation animation : animData.anims) {
-				BlenderTrack track = this.getTrack(owner, animData.skeleton, animation);
-				Quaternion[] rotations = track.getRotations();
-				float[] angles = new float[3];
-				int maxFrames = rotations.length;
-				for (int frame = 0; frame < maxFrames; ++frame) {
-					rotations[frame].toAngles(angles);
-					this.rotLimit(angles, ipo.calculateValue(frame));
-					rotations[frame].fromAngles(angles);
-				}
-				track.setKeyframes(track.getTimes(), track.getTranslations(), rotations, track.getScales());
-			}
-		}
-
-		if (owner instanceof Spatial) {
-			Transform ownerTransform = this.owner.getTransform();
-			float[] angles = ownerTransform.getRotation().toAngles(null);
-			this.rotLimit(angles, ipo.calculateValue(0));
-			ownerTransform.getRotation().fromAngles(angles);
-			this.owner.applyTransform(ownerTransform);
-		}
-	}
-
-	/**
-	 * This method computes new constrained angles.
-	 * 
-	 * @param angles
-	 *            angles to be altered
-	 * @param influence
-	 *            the alteration influence
-	 */
-	private void rotLimit(float[] angles, float influence) {
-		if ((flag & LIMIT_XROT) != 0) {
-			float difference = 0.0f;
-			if (angles[0] < limits[0][0]) {
-				difference = (angles[0] - limits[0][0]) * influence;
-			} else if (angles[0] > limits[0][1]) {
-				difference = (angles[0] - limits[0][1]) * influence;
-			}
-			angles[0] -= difference;
-		}
-		if ((flag & LIMIT_YROT) != 0) {
-			float difference = 0.0f;
-			if (angles[1] < limits[1][0]) {
-				difference = (angles[1] - limits[1][0]) * influence;
-			} else if (angles[1] > limits[1][1]) {
-				difference = (angles[1] - limits[1][1]) * influence;
-			}
-			angles[1] -= difference;
-		}
-		if ((flag & LIMIT_ZROT) != 0) {
-			float difference = 0.0f;
-			if (angles[2] < limits[2][0]) {
-				difference = (angles[2] - limits[2][0]) * influence;
-			} else if (angles[2] > limits[2][1]) {
-				difference = (angles[2] - limits[2][1]) * influence;
-			}
-			angles[2] -= difference;
-		}
-	}
-
-	/**
-	 * This method is called before baking (performes its operations only once).
-	 * It is important to update the state of the limits and owner/target before
-	 * baking the constraint.
-	 */
-	private void update() {
-		if (!updated) {
-			updated = true;
-			if (owner != null) {
-				owner.update();
-			}
-			if (target != null) {
-				target.update();
-			}
-			if (this.owner.getObject() instanceof Bone) {// for bones we need to
-															// change the sign
-															// of the limits
-				for (int i = 0; i < limits.length; ++i) {
-					limits[i][0] *= -1;
-					limits[i][1] *= -1;
-				}
-			}
-
-			// sorting the limits (lower is always first)
-			for (int i = 0; i < limits.length; ++i) {
-				if (limits[i][0] > limits[i][1]) {
-					float temp = limits[i][0];
-					limits[i][0] = limits[i][1];
-					limits[i][1] = temp;
-				}
-			}
-		}
-	}
-}

+ 0 - 45
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSameVolume.java

@@ -1,45 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-
-/**
- * This class represents 'Same volume' constraint type in blender.
- * 
- * @author Marcin Roguski (Kaelthas)
- */
-/*package*/ class ConstraintSameVolume extends Constraint {
-	private static final Logger LOGGER = Logger.getLogger(ConstraintSameVolume.class.getName());
-	
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintSameVolume(Structure constraintStructure, Long ownerOMA,
-			Ipo influenceIpo, BlenderContext blenderContext)
-			throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-	}
-
-	@Override
-	protected void bakeConstraint() {
-		// TODO: implement 'Same volume' constraint
-		LOGGER.log(Level.WARNING, "'Same volume' constraint NOT implemented!");
-	}
-}

+ 0 - 98
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSizeLike.java

@@ -1,98 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import com.jme3.animation.Animation;
-import com.jme3.math.Transform;
-import com.jme3.math.Vector3f;
-import com.jme3.scene.Spatial;
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-import com.jme3.scene.plugins.ogre.AnimData;
-
-/**
- * This class represents 'Size like' constraint type in blender.
- * @author Marcin Roguski (Kaelthas)
- */
-/*package*/ class ConstraintSizeLike extends Constraint {
-	private static final int SIZELIKE_X = 0x01;
-	private static final int SIZELIKE_Y = 0x02;
-	private static final int SIZELIKE_Z = 0x04;
-	private static final int LOCLIKE_OFFSET = 0x80;
-    
-	protected int flag;
-	
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintSizeLike(Structure constraintStructure, Long ownerOMA,
-			Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-		
-		flag = ((Number) data.getFieldValue("flag")).intValue();
-		if(blenderContext.getBlenderKey().isFixUpAxis()) {
-			//swapping Y and X limits flag in the bitwise flag
-			int y = flag & SIZELIKE_Y;
-			int z = flag & SIZELIKE_Z;
-			flag &= SIZELIKE_X | LOCLIKE_OFFSET;//clear the other flags to swap them
-			flag |= y << 1;
-			flag |= z >> 1;
-		}
-	}
-
-	@Override
-	protected void bakeConstraint() {
-		Object owner = this.owner.getObject();
-		AnimData animData = blenderContext.getAnimData(this.owner.getOma());
-		if(animData != null) {
-			Transform targetTransform = this.target.getTransform();
-			Vector3f targetScale = targetTransform.getScale();
-			for(Animation animation : animData.anims) {
-				BlenderTrack track = this.getTrack(owner, animData.skeleton, animation);
-				Vector3f[] scales = track.getScales();
-				int maxFrames = scales.length;
-				for (int frame = 0; frame < maxFrames; ++frame) {
-					this.sizeLike(scales[frame], targetScale, ipo.calculateValue(frame));
-				}
-				track.setKeyframes(track.getTimes(), track.getTranslations(), track.getRotations(), scales);
-			}
-		}
-		
-		if(owner instanceof Spatial) {
-			Transform targetTransform = this.target.getTransform();
-			Transform ownerTransform = this.owner.getTransform();
-			this.sizeLike(ownerTransform.getScale(), targetTransform.getScale(), ipo.calculateValue(0));
-			this.owner.applyTransform(ownerTransform);
-		}
-	}
-	
-	private void sizeLike(Vector3f ownerScale, Vector3f targetScale, float influence) {
-		Vector3f offset = Vector3f.ZERO;
-		if ((flag & LOCLIKE_OFFSET) != 0) {//we add the original scale to the copied scale
-			offset = ownerScale.clone();
-		}
-
-		if ((flag & SIZELIKE_X) != 0) {
-			ownerScale.x = targetScale.x * influence + (1.0f - influence) * ownerScale.x;
-		}
-		if ((flag & SIZELIKE_Y) != 0) {
-			ownerScale.y = targetScale.y * influence + (1.0f - influence) * ownerScale.y;
-		}
-		if ((flag & SIZELIKE_Z) != 0) {
-			ownerScale.z = targetScale.z * influence + (1.0f - influence) * ownerScale.z;
-		}
-		ownerScale.addLocal(offset);
-	}
-}

+ 0 - 131
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSizeLimit.java

@@ -1,131 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import com.jme3.animation.Animation;
-import com.jme3.math.Transform;
-import com.jme3.math.Vector3f;
-import com.jme3.scene.Spatial;
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-import com.jme3.scene.plugins.ogre.AnimData;
-
-/**
- * This class represents 'Size limit' constraint type in blender.
- * @author Marcin Roguski (Kaelthas)
- */
-/*package*/ class ConstraintSizeLimit extends Constraint {
-	private static final int LIMIT_XMIN = 0x01;
-	private static final int LIMIT_XMAX = 0x02;
-	private static final int LIMIT_YMIN = 0x04;
-	private static final int LIMIT_YMAX = 0x08;
-	private static final int LIMIT_ZMIN = 0x10;
-	private static final int LIMIT_ZMAX = 0x20;
-	
-	protected float[][] limits = new float[3][2];
-    protected int flag;
-	
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintSizeLimit(Structure constraintStructure, Long ownerOMA,
-			Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-		
-		flag = ((Number) data.getFieldValue("flag")).intValue();
-		if(blenderContext.getBlenderKey().isFixUpAxis()) {
-			limits[0][0] = ((Number) data.getFieldValue("xmin")).floatValue();
-			limits[0][1] = ((Number) data.getFieldValue("xmax")).floatValue();
-			limits[2][0] = -((Number) data.getFieldValue("ymin")).floatValue();
-			limits[2][1] = -((Number) data.getFieldValue("ymax")).floatValue();
-			limits[1][0] = ((Number) data.getFieldValue("zmin")).floatValue();
-			limits[1][1] = ((Number) data.getFieldValue("zmax")).floatValue();
-			
-			//swapping Y and X limits flag in the bitwise flag
-			int ymin = flag & LIMIT_YMIN;
-			int ymax = flag & LIMIT_YMAX;
-			int zmin = flag & LIMIT_ZMIN;
-			int zmax = flag & LIMIT_ZMAX;
-			flag &= LIMIT_XMIN | LIMIT_XMAX;//clear the other flags to swap them
-			flag |= ymin << 2;
-			flag |= ymax << 2;
-			flag |= zmin >> 2;
-			flag |= zmax >> 2;
-		} else {
-			limits[0][0] = ((Number) data.getFieldValue("xmin")).floatValue();
-			limits[0][1] = ((Number) data.getFieldValue("xmax")).floatValue();
-			limits[1][0] = ((Number) data.getFieldValue("ymin")).floatValue();
-			limits[1][1] = ((Number) data.getFieldValue("ymax")).floatValue();
-			limits[2][0] = ((Number) data.getFieldValue("zmin")).floatValue();
-			limits[2][1] = ((Number) data.getFieldValue("zmax")).floatValue();
-		}
-	}
-
-	@Override
-	protected void bakeConstraint() {
-		Object owner = this.owner.getObject();
-		AnimData animData = blenderContext.getAnimData(this.owner.getOma());
-		if(animData != null) {
-			for(Animation animation : animData.anims) {
-				BlenderTrack track = this.getTrack(owner, animData.skeleton, animation);
-				Vector3f[] scales = track.getScales();
-				int maxFrames = scales.length;
-				for (int frame = 0; frame < maxFrames; ++frame) {
-					this.sizeLimit(scales[frame], ipo.calculateValue(frame));
-				}
-				track.setKeyframes(track.getTimes(), track.getTranslations(), track.getRotations(), scales);
-			}
-		}
-		
-		if(owner instanceof Spatial) {
-			Transform ownerTransform = this.owner.getTransform();
-			this.sizeLimit(ownerTransform.getScale(), ipo.calculateValue(0));
-			this.owner.applyTransform(ownerTransform);
-		}
-	}
-	
-	private void sizeLimit(Vector3f scale, float influence) {
-		if ((flag & LIMIT_XMIN) != 0) {
-			if (scale.x < limits[0][0]) {
-				scale.x -= (scale.x - limits[0][0]) * influence;
-			}
-		}
-		if ((flag & LIMIT_XMAX) != 0) {
-			if (scale.x > limits[0][1]) {
-				scale.x -= (scale.x - limits[0][1]) * influence;
-			}
-		}
-		if ((flag & LIMIT_YMIN) != 0) {
-			if (scale.y < limits[1][0]) {
-				scale.y -= (scale.y - limits[1][0]) * influence;
-			}
-		}
-		if ((flag & LIMIT_YMAX) != 0) {
-			if (scale.y > limits[1][1]) {
-				scale.y -= (scale.y - limits[1][1]) * influence;
-			}
-		}
-		if ((flag & LIMIT_ZMIN) != 0) {
-			if (scale.z < limits[2][0]) {
-				scale.z -= (scale.z - limits[2][0]) * influence;
-			}
-		}
-		if ((flag & LIMIT_ZMAX) != 0) {
-			if (scale.z > limits[2][1]) {
-				scale.z -= (scale.z - limits[2][1]) * influence;
-			}
-		}
-	}
-}

+ 0 - 43
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSplineInverseKinematic.java

@@ -1,43 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * The spline inverse kinematic constraint. Available for blender 2.50+.
- * @author Marcin Roguski (Kaelthas)
- */
-/*package*/ class ConstraintSplineInverseKinematic extends Constraint {
-	private static final Logger LOGGER = Logger.getLogger(ConstraintSplineInverseKinematic.class.getName());
-	
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintSplineInverseKinematic(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo,
-			BlenderContext blenderContext) throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-		// TODO Auto-generated constructor stub
-	}
-
-	@Override
-	protected void bakeConstraint() {
-		// TODO Auto-generated method stub
-		LOGGER.log(Level.WARNING, "'Splie IK' constraint NOT implemented!");
-	}
-}

+ 0 - 42
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintStretchTo.java

@@ -1,42 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * This class represents 'Stretch to' constraint type in blender.
- * @author Marcin Roguski (Kaelthas)
- */
-/*package*/ class ConstraintStretchTo extends Constraint {
-	private static final Logger LOGGER = Logger.getLogger(ConstraintStretchTo.class.getName());
-	
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintStretchTo(Structure constraintStructure, Long ownerOMA,
-			Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-	}
-
-	@Override
-	protected void bakeConstraint() {
-		// TODO: implement 'Stretch to' constraint
-		LOGGER.log(Level.WARNING, "'Stretch to' constraint NOT implemented!");
-	}
-}

+ 0 - 45
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintTrackTo.java

@@ -1,45 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-
-/**
- * This class represents 'Track to' constraint type in blender.
- * 
- * @author Marcin Roguski (Kaelthas)
- */
-/* package */class ConstraintTrackTo extends Constraint {
-	private static final Logger LOGGER = Logger.getLogger(ConstraintTrackTo.class.getName());
-
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintTrackTo(Structure constraintStructure, Long ownerOMA,
-			Ipo influenceIpo, BlenderContext blenderContext)
-			throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-	}
-
-	@Override
-	protected void bakeConstraint() {
-		// TODO: implement 'Track to' constraint
-		LOGGER.log(Level.WARNING, "'Track to' constraint NOT implemented!");
-	}
-}

+ 0 - 45
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintTransLike.java

@@ -1,45 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-
-/**
- * This class represents 'Trans like' constraint type in blender.
- * 
- * @author Marcin Roguski (Kaelthas)
- */
-/*package*/ class ConstraintTransLike extends Constraint {
-	private static final Logger LOGGER = Logger.getLogger(ConstraintTransLike.class.getName());
-	
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintTransLike(Structure constraintStructure, Long ownerOMA,
-			Ipo influenceIpo, BlenderContext blenderContext)
-			throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-	}
-
-	@Override
-	protected void bakeConstraint() {
-		// TODO: implement 'Trans like' constraint
-		LOGGER.log(Level.WARNING, "'Trans like' constraint NOT implemented!");
-	}
-}

+ 0 - 42
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintTransform.java

@@ -1,42 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.Structure;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * This class represents 'Transform' constraint type in blender.
- * @author Marcin Roguski (Kaelthas)
- */
-/*package*/ class ConstraintTransform extends Constraint {
-	private static final Logger LOGGER = Logger.getLogger(ConstraintAction.class.getName());
-	
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintTransform(Structure constraintStructure, Long ownerOMA,
-			Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-	}
-
-	@Override
-	protected void bakeConstraint() {
-		// TODO: implement 'Transform' constraint
-		LOGGER.log(Level.WARNING, "'Transform' constraint NOT implemented!");
-	}
-}

+ 0 - 302
engine/src/blender/com/jme3/scene/plugins/blender/constraints/Feature.java

@@ -1,302 +0,0 @@
-package com.jme3.scene.plugins.blender.constraints;
-
-import com.jme3.animation.Bone;
-import com.jme3.math.Matrix4f;
-import com.jme3.math.Quaternion;
-import com.jme3.math.Transform;
-import com.jme3.math.Vector3f;
-import com.jme3.scene.Spatial;
-import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.BlenderContext.LoadedFeatureDataType;
-import com.jme3.scene.plugins.blender.constraints.Constraint.Space;
-import com.jme3.scene.plugins.blender.file.DynamicArray;
-import com.jme3.scene.plugins.blender.file.Structure;
-
-/**
- * This class represents either owner or target of the constraint. It has the
- * common methods that take the evalueation space of the feature.
- * 
- * @author Marcin Roguski (Kaelthas)
- */
-/* package */class Feature {
-	/** The evalueation space. */
-	protected Space				space;
-	/** Old memory address of the feature. */
-	protected Long				oma;
-	/** The spatial that is hold by the Feature. */
-	protected Spatial			spatial;
-	/** The bone that is hold by the Feature. */
-	protected Bone				bone;
-	/** The blender context. */
-	protected BlenderContext	blenderContext;
-
-	/**
-	 * Constructs the feature. This object should be loaded later
-	 * when it is read from the blender file.
-	 * The update method should be called before the feature is used.
-	 * 
-	 * @param space
-	 *            the spatial's evaluation space
-	 * @param oma
-	 *            the spatial's old memory address
-	 * @param blenderContext
-	 *            the blender context
-	 */
-	public Feature(Space space, Long oma, BlenderContext blenderContext) {
-		this.space = space;
-		this.oma = oma;
-		this.blenderContext = blenderContext;
-	}
-	
-	/**
-	 * Constructs the feature based on spatial.
-	 * 
-	 * @param spatial
-	 *            the spatial
-	 * @param space
-	 *            the spatial's evaluation space
-	 * @param oma
-	 *            the spatial's old memory address
-	 * @param blenderContext
-	 *            the blender context
-	 */
-	public Feature(Spatial spatial, Space space, Long oma, BlenderContext blenderContext) {
-		this(space, oma, blenderContext);
-		this.blenderContext = blenderContext;
-	}
-
-	/**
-	 * Constructs the feature based on bone.
-	 * 
-	 * @param bone
-	 *            the bone
-	 * @param space
-	 *            the bone evaluation space
-	 * @param oma
-	 *            the bone old memory address
-	 * @param blenderContext
-	 *            the blender context
-	 */
-	public Feature(Bone bone, Space space, Long oma, BlenderContext blenderContext) {
-		this(space, oma, blenderContext);
-		this.bone = bone;
-	}
-	
-	/**
-	 * This method should be called before the feature is used.
-	 * It may happen that the object this feature refers to was not yet loaded from blend file
-	 * when the instance of this class was created.
-	 */
-	public void update() {
-		Object owner = blenderContext.getLoadedFeature(oma, LoadedFeatureDataType.LOADED_FEATURE);
-		if(owner instanceof Spatial) {
-			this.spatial = (Spatial) owner;
-		} else if(owner instanceof Bone) {
-			this.bone = (Bone) owner;
-		} else {
-			throw new IllegalStateException("Unknown type of owner: " + owner.getClass());
-		}
-	}
-	
-	/**
-	 * @return the feature's old memory address
-	 */
-	public Long getOma() {
-		return oma;
-	}
-
-	/**
-	 * @return the object held by the feature (either bone or spatial)
-	 */
-	public Object getObject() {
-		if (spatial != null) {
-			return spatial;
-		}
-		return bone;
-	}
-
-	/**
-	 * @return the feature's transform depending on the evaluation space
-	 */
-	@SuppressWarnings("unchecked")
-	public Transform getTransform() {
-		if (spatial != null) {
-			switch (space) {
-				case CONSTRAINT_SPACE_LOCAL:
-					Structure targetStructure = (Structure) blenderContext.getLoadedFeature(oma, LoadedFeatureDataType.LOADED_STRUCTURE);
-
-					DynamicArray<Number> locArray = ((DynamicArray<Number>) targetStructure.getFieldValue("loc"));
-					Vector3f loc = new Vector3f(locArray.get(0).floatValue(), locArray.get(1).floatValue(), locArray.get(2).floatValue());
-					DynamicArray<Number> rotArray = ((DynamicArray<Number>) targetStructure.getFieldValue("rot"));
-					Quaternion rot = new Quaternion(new float[] { rotArray.get(0).floatValue(), rotArray.get(1).floatValue(), rotArray.get(2).floatValue() });
-					DynamicArray<Number> sizeArray = ((DynamicArray<Number>) targetStructure.getFieldValue("size"));
-					Vector3f size = new Vector3f(sizeArray.get(0).floatValue(), sizeArray.get(1).floatValue(), sizeArray.get(2).floatValue());
-
-					if (blenderContext.getBlenderKey().isFixUpAxis()) {
-						float y = loc.y;
-						loc.y = loc.z;
-						loc.z = -y;
-
-						y = rot.getY();
-						float z = rot.getZ();
-						rot.set(rot.getX(), z, -y, rot.getW());
-
-						y = size.y;
-						size.y = size.z;
-						size.z = y;
-					}
-
-					Transform result = new Transform(loc, rot);
-					result.setScale(size);
-					return result;
-				case CONSTRAINT_SPACE_WORLD:
-					return spatial.getWorldTransform();
-				default:
-					throw new IllegalStateException("Invalid space type for target object: " + space.toString());
-			}
-		}
-		// Bone
-		switch (space) {
-			case CONSTRAINT_SPACE_LOCAL:
-				Transform localTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation());
-				localTransform.setScale(bone.getLocalScale());
-				return localTransform;
-			case CONSTRAINT_SPACE_WORLD:
-				Transform worldTransform = new Transform(bone.getWorldBindPosition(), bone.getWorldBindRotation());
-				worldTransform.setScale(bone.getWorldBindScale());
-				return worldTransform;
-			case CONSTRAINT_SPACE_POSE:
-				Transform poseTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation());
-				poseTransform.setScale(bone.getLocalScale());
-				return poseTransform;
-			case CONSTRAINT_SPACE_PARLOCAL:
-				Transform parentLocalTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation());
-				parentLocalTransform.setScale(bone.getLocalScale());
-				return parentLocalTransform;
-			default:
-				throw new IllegalStateException("Invalid space type for target object: " + space.toString());
-		}
-	}
-
-	/**
-	 * This method applies the given transform to the feature in the proper
-	 * evaluation space.
-	 * 
-	 * @param transform
-	 *            the transform to be applied
-	 */
-	public void applyTransform(Transform transform) {
-		if (spatial != null) {
-			switch (space) {
-				case CONSTRAINT_SPACE_LOCAL:
-					Transform ownerLocalTransform = spatial.getLocalTransform();
-					ownerLocalTransform.getTranslation().addLocal(transform.getTranslation());
-					ownerLocalTransform.getRotation().multLocal(transform.getRotation());
-					ownerLocalTransform.getScale().multLocal(transform.getScale());
-					break;
-				case CONSTRAINT_SPACE_WORLD:
-					Matrix4f m = this.getParentWorldTransformMatrix();
-					m.invertLocal();
-					Matrix4f matrix = this.toMatrix(transform);
-					m.multLocal(matrix);
-
-					float scaleX = (float) Math.sqrt(m.m00 * m.m00 + m.m10 * m.m10 + m.m20 * m.m20);
-					float scaleY = (float) Math.sqrt(m.m01 * m.m01 + m.m11 * m.m11 + m.m21 * m.m21);
-					float scaleZ = (float) Math.sqrt(m.m02 * m.m02 + m.m12 * m.m12 + m.m22 * m.m22);
-
-					transform.setTranslation(m.toTranslationVector());
-					transform.setRotation(m.toRotationQuat());
-					transform.setScale(scaleX, scaleY, scaleZ);
-					spatial.setLocalTransform(transform);
-					break;
-				case CONSTRAINT_SPACE_PARLOCAL:
-				case CONSTRAINT_SPACE_POSE:
-					throw new IllegalStateException("Invalid space type (" + space.toString() + ") for owner object.");
-				default:
-					throw new IllegalStateException("Invalid space type for target object: " + space.toString());
-			}
-		} else {// Bone
-			switch (space) {
-				case CONSTRAINT_SPACE_LOCAL:
-					bone.setBindTransforms(transform.getTranslation(), transform.getRotation(), transform.getScale());
-					break;
-				case CONSTRAINT_SPACE_WORLD:
-					Matrix4f m = this.getParentWorldTransformMatrix();
-//					m.invertLocal();
-					transform.setTranslation(m.mult(transform.getTranslation()));
-					transform.setRotation(m.mult(transform.getRotation(), null));
-					transform.setScale(transform.getScale());
-					bone.setBindTransforms(transform.getTranslation(), transform.getRotation(), transform.getScale());
-//					float x = FastMath.HALF_PI/2;
-//					float y = -FastMath.HALF_PI;
-//					float z = -FastMath.HALF_PI/2;
-//					bone.setBindTransforms(new Vector3f(0,0,0), new Quaternion().fromAngles(x, y, z), new Vector3f(1,1,1));
-					break;
-				case CONSTRAINT_SPACE_PARLOCAL:
-					Vector3f parentLocalTranslation = bone.getLocalPosition().add(transform.getTranslation());
-					Quaternion parentLocalRotation = bone.getLocalRotation().mult(transform.getRotation());
-					bone.setBindTransforms(parentLocalTranslation, parentLocalRotation, transform.getScale());
-					break;
-				case CONSTRAINT_SPACE_POSE:
-					bone.setBindTransforms(transform.getTranslation(), transform.getRotation(), transform.getScale());
-					break;
-				default:
-					throw new IllegalStateException("Invalid space type for target object: " + space.toString());
-			}
-		}
-	}
-
-	/**
-	 * @return world transform matrix of the feature
-	 */
-	public Matrix4f getWorldTransformMatrix() {
-		if (spatial != null) {
-			Matrix4f result = new Matrix4f();
-			Transform t = spatial.getWorldTransform();
-			result.setTransform(t.getTranslation(), t.getScale(), t.getRotation().toRotationMatrix());
-			return result;
-		}
-		// Bone
-		Matrix4f result = new Matrix4f();
-		result.setTransform(bone.getWorldBindPosition(), bone.getWorldBindScale(), bone.getWorldBindRotation().toRotationMatrix());
-		return result;
-	}
-
-	/**
-	 * @return world transform matrix of the feature's parent or identity matrix
-	 *         if the feature has no parent
-	 */
-	public Matrix4f getParentWorldTransformMatrix() {
-		Matrix4f result = new Matrix4f();
-		if (spatial != null) {
-			if (spatial.getParent() != null) {
-				Transform t = spatial.getParent().getWorldTransform();
-				result.setTransform(t.getTranslation(), t.getScale(), t.getRotation().toRotationMatrix());
-			}
-		} else {// Bone
-			Bone parent = bone.getParent();
-			if (parent != null) {
-				result.setTransform(parent.getWorldBindPosition(), parent.getWorldBindScale(), parent.getWorldBindRotation().toRotationMatrix());
-			}
-		}
-		return result;
-	}
-
-	/**
-	 * Converts given transform to the matrix.
-	 * 
-	 * @param transform
-	 *            the transform to be converted
-	 * @return 4x4 matri that represents the given transform
-	 */
-	protected Matrix4f toMatrix(Transform transform) {
-		Matrix4f result = Matrix4f.IDENTITY;
-		if (transform != null) {
-			result = new Matrix4f();
-			result.setTranslation(transform.getTranslation());
-			result.setRotationQuaternion(transform.getRotation());
-			result.setScale(transform.getScale());
-		}
-		return result;
-	}
-}

+ 32 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/SkeletonConstraint.java

@@ -0,0 +1,32 @@
+package com.jme3.scene.plugins.blender.constraints;
+
+import java.util.logging.Logger;
+
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.animations.Ipo;
+import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * Constraint applied on the skeleton. This constraint is here only to make the
+ * application not crash when loads constraints applied to armature. But
+ * skeleton movement is not supported by jme so the constraint will never be
+ * applied.
+ * 
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class SkeletonConstraint extends Constraint {
+	private static final Logger LOGGER = Logger.getLogger(SkeletonConstraint.class.getName());
+	
+	public SkeletonConstraint(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
+		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
+	}
+
+	@Override
+	public void performBakingOperation() {
+		LOGGER.warning("Applying constraints to skeleton is not supported.");
+	}
+
+	@Override
+	protected void prepareTracksForApplyingConstraints() { }
+}

+ 146 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/SpatialConstraint.java

@@ -0,0 +1,146 @@
+package com.jme3.scene.plugins.blender.constraints;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+
+import com.jme3.animation.AnimControl;
+import com.jme3.animation.Animation;
+import com.jme3.animation.SpatialTrack;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Transform;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.BlenderContext.LoadedFeatureDataType;
+import com.jme3.scene.plugins.blender.animations.Ipo;
+import com.jme3.scene.plugins.blender.constraints.ConstraintHelper.Space;
+import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
+import com.jme3.scene.plugins.blender.file.Structure;
+import com.jme3.scene.plugins.ogre.AnimData;
+
+/**
+ * Constraint applied on the spatial objects.
+ * This includes: nodes, cameras nodes and light nodes.
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class SpatialConstraint extends Constraint {
+	/** The owner of the constraint. */
+	private Spatial owner;
+	/** The target of the constraint. */
+	private Object target;
+	
+	public SpatialConstraint(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext)
+			throws BlenderFileException {
+		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
+	}
+	
+	@Override
+	public void performBakingOperation() {
+		this.owner = (Spatial) blenderContext.getLoadedFeature(ownerOMA, LoadedFeatureDataType.LOADED_FEATURE);
+		this.target = targetOMA != null ? blenderContext.getLoadedFeature(targetOMA, LoadedFeatureDataType.LOADED_FEATURE) : null;
+		this.prepareTracksForApplyingConstraints();
+		
+		//apply static constraint
+		Transform ownerTransform = constraintHelper.getNodeObjectTransform(ownerSpace, ownerOMA, blenderContext);
+		Transform targetTransform = targetOMA != null ? constraintHelper.getNodeObjectTransform(targetSpace, targetOMA, blenderContext) : null;
+		constraintDefinition.bake(ownerTransform, targetTransform, null, null, this.ipo);
+		constraintHelper.applyTransform(owner, ownerSpace, ownerTransform);
+		
+		//apply dynamic constraint
+		AnimData animData = blenderContext.getAnimData(ownerOMA);
+		if(animData != null) {
+			for(Animation animation : animData.anims) {
+				SpatialTrack ownerTrack = constraintHelper.getTrack(owner, animation);
+				
+				AnimData targetAnimData = blenderContext.getAnimData(targetOMA);
+				SpatialTrack targetTrack = null;
+				if(targetAnimData != null) {
+					targetTrack = constraintHelper.getTrack((Spatial)target, targetAnimData.anims.get(0));
+				}
+				
+				constraintDefinition.bake(ownerTransform, targetTransform, ownerTrack, targetTrack, this.ipo);
+			}
+		}
+	}
+	
+	@Override
+	protected void prepareTracksForApplyingConstraints() {
+		Long[] spatialsOMAs = new Long[] { ownerOMA, targetOMA };
+		Space[] spaces = new Space[] { ownerSpace, targetSpace };
+		
+		//creating animations for current objects if at least on of their parents have an animation
+		for (int i = 0; i < spatialsOMAs.length; ++i) {
+			Long oma = spatialsOMAs[i];
+			if(oma != null && oma > 0L) {
+				AnimData animData = blenderContext.getAnimData(oma);
+				if(animData == null) {
+					Spatial currentSpatial = (Spatial)blenderContext.getLoadedFeature(oma, LoadedFeatureDataType.LOADED_FEATURE);
+					Spatial parent = currentSpatial.getParent();
+					while(parent != null && animData == null) {
+						Structure parentStructure = (Structure)blenderContext.getLoadedFeature(parent.getName(), LoadedFeatureDataType.LOADED_STRUCTURE);
+						if(parentStructure == null) {
+							parent = null;
+						} else {
+							Long parentOma = parentStructure.getOldMemoryAddress();
+							animData = blenderContext.getAnimData(parentOma);
+							parent = parent.getParent();
+						}
+					}
+					
+					if(animData != null) {//create anim data for the current object
+						this.applyAnimData(currentSpatial, oma, spaces[i], animData.anims.get(0));
+					}
+				}
+			}
+		}
+		
+		//creating animation for owner if it doesn't have one already and if the target has it
+		AnimData animData = blenderContext.getAnimData(ownerOMA);
+		if(animData == null) {
+			AnimData targetAnimData = blenderContext.getAnimData(targetOMA);
+			if(targetAnimData != null) {
+				this.applyAnimData(owner, ownerOMA, ownerSpace, targetAnimData.anims.get(0));
+			}
+		}
+	}
+	
+	/**
+	 * This method applies spatial transform on each frame of the given
+	 * animations.
+	 * 
+	 * @param spatial
+	 *            the spatial
+	 * @param spatialOma
+	 *            the OMA of the given spatial
+	 * @param space
+	 *            the space we compute the transform in
+	 * @param referenceAnimation
+	 *            the object containing the animations
+	 */
+	private void applyAnimData(Spatial spatial, Long spatialOma, Space space, Animation referenceAnimation) {
+		ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class);
+		Transform transform = constraintHelper.getNodeObjectTransform(space, spatialOma, blenderContext);
+		
+		SpatialTrack parentTrack = (SpatialTrack) referenceAnimation.getTracks()[0];
+		
+		HashMap<String, Animation> anims = new HashMap<String, Animation>(1);
+		Animation animation = new Animation(spatial.getName(), referenceAnimation.getLength());
+		anims.put(spatial.getName(), animation);
+		
+		float[] times = parentTrack.getTimes();
+		Vector3f[] translations = new Vector3f[times.length];
+		Quaternion[] rotations = new Quaternion[times.length];
+		Vector3f[] scales = new Vector3f[times.length];
+		Arrays.fill(translations, transform.getTranslation());
+		Arrays.fill(rotations, transform.getRotation());
+		Arrays.fill(scales, transform.getScale());
+		animation.addTrack(new SpatialTrack(times, translations, rotations, scales));
+		
+		AnimControl control = new AnimControl(null);
+		control.setAnimations(anims);
+		spatial.addControl(control);
+		
+		blenderContext.setAnimData(spatialOma, new AnimData(null, new ArrayList<Animation>(anims.values())));
+	}
+}

+ 244 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinition.java

@@ -0,0 +1,244 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import java.io.IOException;
+
+import com.jme3.animation.AnimChannel;
+import com.jme3.animation.AnimControl;
+import com.jme3.animation.BoneTrack;
+import com.jme3.animation.SpatialTrack;
+import com.jme3.animation.Track;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.math.FastMath;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Transform;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.animations.Ipo;
+import com.jme3.scene.plugins.blender.file.Structure;
+import com.jme3.util.TempVars;
+
+public abstract class ConstraintDefinition {
+	protected int flag;
+	
+	public ConstraintDefinition(Structure constraintData, BlenderContext blenderContext) {
+		if(constraintData != null) {//Null constraint has no data
+			Number flag = (Number)constraintData.getFieldValue("flag");
+			if(flag != null) {
+				this.flag = flag.intValue();
+			}
+		}
+	}
+	
+	public void bake(Transform ownerTransform, Transform targetTransform, Track ownerTrack, Track targetTrack, Ipo influenceIpo) {
+		TrackWrapper ownerWrapperTrack = ownerTrack != null ? new TrackWrapper(ownerTrack) : null;
+		TrackWrapper targetWrapperTrack = targetTrack != null ? new TrackWrapper(targetTrack) : null;
+		
+		//uruchamiamy bake dla transformat zale¿nie od tego, które argumenty s¹ nullami, a które - nie
+		this.bake(ownerTransform, targetTransform, influenceIpo.calculateValue(0));
+		if(ownerWrapperTrack != null) {
+			float[] ownerTimes = ownerWrapperTrack.getTimes();
+			Vector3f[] translations = ownerWrapperTrack.getTranslations();
+			Quaternion[] rotations = ownerWrapperTrack.getRotations();
+			Vector3f[] scales = ownerWrapperTrack.getScales();
+			
+			float[] targetTimes = targetWrapperTrack == null ? null : targetWrapperTrack.getTimes();
+			Vector3f[] targetTranslations = targetWrapperTrack == null ? null : targetWrapperTrack.getTranslations();
+			Quaternion[] targetRotations = targetWrapperTrack == null ? null : targetWrapperTrack.getRotations();
+			Vector3f[] targetScales = targetWrapperTrack == null ? null : targetWrapperTrack.getScales();
+			Vector3f translation = new Vector3f(), scale = new Vector3f();
+			Quaternion rotation = new Quaternion();
+			
+			Transform ownerTemp = new Transform(), targetTemp = new Transform();
+			for (int i = 0; i <ownerTimes.length; ++i) {
+				float t = ownerTimes[i];
+				ownerTemp.setTranslation(translations[i]);
+				ownerTemp.setRotation(rotations[i]);
+				ownerTemp.setScale(scales[i]);
+				if(targetWrapperTrack == null) {
+					this.bake(ownerTemp, targetTransform, influenceIpo.calculateValue(i));
+				} else {
+					//getting the values that are the interpolation of the target track for the time 't'
+					this.interpolate(targetTranslations, targetTimes, t, translation);
+					this.interpolate(targetRotations, targetTimes, t, rotation);
+					this.interpolate(targetScales, targetTimes, t, scale);
+					
+					targetTemp.setTranslation(translation);
+					targetTemp.setRotation(rotation);
+					targetTemp.setScale(scale);
+					
+					this.bake(ownerTemp, targetTemp, influenceIpo.calculateValue(i));
+				}
+				//need to clone here because each of the arrays will reference the same instance if they hold the same value in the compact array
+				translations[i] = ownerTemp.getTranslation().clone();
+				rotations[i] = ownerTemp.getRotation().clone();
+				scales[i] = ownerTemp.getScale().clone();
+			}
+			ownerWrapperTrack.setKeyframes(ownerTimes, translations, rotations, scales);
+		}
+	}
+	
+	protected abstract void bake(Transform ownerTransform, Transform targetTransform, float influence);
+	
+	private void interpolate(Vector3f[] targetVectors, float[] targetTimes, float currentTime, Vector3f result) {
+		int index = 0;
+		for (int i = 1; i < targetTimes.length; ++i) {
+			if(targetTimes[i] < currentTime) {
+				++index;
+			} else {
+				break;
+			}
+		}
+		if(index >= targetTimes.length - 1) {
+			result.set(targetVectors[targetTimes.length - 1]);
+		} else {
+			float delta = targetTimes[index + 1] - targetTimes[index];
+			if(delta == 0.0f) {
+				result.set(targetVectors[index + 1]);
+			} else {
+				float scale = (currentTime - targetTimes[index])/(targetTimes[index + 1] - targetTimes[index]);
+				FastMath.interpolateLinear(scale, targetVectors[index], targetVectors[index + 1], result);
+			}
+		}
+	}
+	
+	private void interpolate(Quaternion[] targetQuaternions, float[] targetTimes, float currentTime, Quaternion result) {
+		int index = 0;
+		for (int i = 1; i < targetTimes.length; ++i) {
+			if(targetTimes[i] < currentTime) {
+				++index;
+			} else {
+				break;
+			}
+		}
+		if(index >= targetTimes.length - 1) {
+			result.set(targetQuaternions[targetTimes.length - 1]);
+		} else {
+			float delta = targetTimes[index + 1] - targetTimes[index];
+			if(delta == 0.0f) {
+				result.set(targetQuaternions[index + 1]);
+			} else {
+				float scale = (currentTime - targetTimes[index])/(targetTimes[index + 1] - targetTimes[index]);
+				result.slerp(targetQuaternions[index], targetQuaternions[index + 1], scale);
+			}
+		}
+	}
+	
+	/**
+	 * This class holds either the bone track or spatial track. Is made to improve
+	 * code readability.
+	 * 
+	 * @author Marcin Roguski (Kaelthas)
+	 */
+	private static class TrackWrapper implements Track {
+		/** The spatial track. */
+		private SpatialTrack spatialTrack;
+		/** The bone track. */
+		private BoneTrack boneTrack;
+
+		/**
+		 * Constructs the object using the given track. The track must be of one of the types:
+		 * <li> BoneTrack
+		 * <li> SpatialTrack
+		 * 
+		 * @param track
+		 *            the animation track
+		 */
+		public TrackWrapper(Track track) {
+			if(track instanceof SpatialTrack) {
+				this.spatialTrack = (SpatialTrack)track;
+			} else if(track instanceof BoneTrack) {
+				this.boneTrack = (BoneTrack)track;
+			} else {
+				throw new IllegalStateException("Unknown track type!");
+			}
+		}
+
+		/**
+		 * @return the array of rotations of this track
+		 */
+		public Quaternion[] getRotations() {
+			if (boneTrack != null) {
+				return boneTrack.getRotations();
+			}
+			return spatialTrack.getRotations();
+		}
+
+		/**
+		 * @return the array of scales for this track
+		 */
+		public Vector3f[] getScales() {
+			if (boneTrack != null) {
+				return boneTrack.getScales();
+			}
+			return spatialTrack.getScales();
+		}
+
+		/**
+		 * @return the arrays of time for this track
+		 */
+		public float[] getTimes() {
+			if (boneTrack != null) {
+				return boneTrack.getTimes();
+			}
+			return spatialTrack.getTimes();
+		}
+
+		/**
+		 * @return the array of translations of this track
+		 */
+		public Vector3f[] getTranslations() {
+			if (boneTrack != null) {
+				return boneTrack.getTranslations();
+			}
+			return spatialTrack.getTranslations();
+		}
+
+		/**
+		 * Set the translations, rotations and scales for this bone track
+		 * 
+		 * @param times
+		 *            a float array with the time of each frame
+		 * @param translations
+		 *            the translation of the bone for each frame
+		 * @param rotations
+		 *            the rotation of the bone for each frame
+		 * @param scales
+		 *            the scale of the bone for each frame
+		 */
+		public void setKeyframes(float[] times, Vector3f[] translations,
+				Quaternion[] rotations, Vector3f[] scales) {
+			if (boneTrack != null) {
+				boneTrack.setKeyframes(times, translations, rotations, scales);
+			} else {
+				spatialTrack.setKeyframes(times, translations, rotations, scales);
+			}
+		}
+
+		public void write(JmeExporter ex) throws IOException { }
+
+		public void read(JmeImporter im) throws IOException { }
+
+		public void setTime(float time, float weight, AnimControl control,
+				AnimChannel channel, TempVars vars) {
+			if (boneTrack != null) {
+				boneTrack.setTime(time, weight, control, channel, vars);
+			} else {
+				spatialTrack.setTime(time, weight, control, channel, vars);
+			}
+		}
+
+		public float getLength() {
+			return spatialTrack == null ? boneTrack.getLength() : spatialTrack
+					.getLength();
+		}
+
+		@Override
+		public TrackWrapper clone() {
+			if (boneTrack != null) {
+				return new TrackWrapper(boneTrack.clone());
+			}
+			return new TrackWrapper(spatialTrack.clone());
+		}
+	}
+}

+ 26 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionAction.java

@@ -0,0 +1,26 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.jme3.math.Transform;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * This class represents 'Action' constraint type in blender.
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class ConstraintDefinitionAction extends ConstraintDefinition {
+	private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionAction.class.getName());
+	
+	public ConstraintDefinitionAction(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+	}
+
+	@Override
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
+		// TODO: implement 'Action' constraint
+		LOGGER.log(Level.WARNING, "'Action' constraint NOT implemented!");
+	}
+}

+ 26 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionChildOf.java

@@ -0,0 +1,26 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.jme3.math.Transform;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * This class represents 'ChildOf' constraint type in blender.
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class ConstraintDefinitionChildOf extends ConstraintDefinition {
+	private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionChildOf.class.getName());
+	
+	public ConstraintDefinitionChildOf(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+	}
+	
+	@Override
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
+		// TODO: implement ChildOf constraint
+		LOGGER.log(Level.WARNING, "ChildOf constraint NOT implemented!");
+	}
+}

+ 26 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionClampTo.java

@@ -0,0 +1,26 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.jme3.math.Transform;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * This class represents 'Clamp to' constraint type in blender.
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class ConstraintDefinitionClampTo extends ConstraintDefinition {
+	private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionClampTo.class.getName());
+	
+	public ConstraintDefinitionClampTo(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+	}
+	
+	@Override
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
+		//TODO: implement when curves are implemented
+		LOGGER.log(Level.INFO, "'Clamp to' not yet implemented!");
+	}
+}

+ 26 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionDampTrack.java

@@ -0,0 +1,26 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.jme3.math.Transform;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * The damp track constraint. Available for blender 2.50+.
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class ConstraintDefinitionDampTrack extends ConstraintDefinition {
+	private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionDampTrack.class.getName());
+	
+	public ConstraintDefinitionDampTrack(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+	}
+	
+	@Override
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
+		// TODO Auto-generated method stub
+		LOGGER.log(Level.WARNING, "'Damp Track' constraint NOT implemented!");
+	}
+}

+ 59 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionDistLimit.java

@@ -0,0 +1,59 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import com.jme3.math.Transform;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * This class represents 'Dist limit' constraint type in blender.
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class ConstraintDefinitionDistLimit extends ConstraintDefinition {
+	private static final int LIMITDIST_INSIDE = 0;
+	private static final int LIMITDIST_OUTSIDE = 1;
+	private static final int LIMITDIST_ONSURFACE = 2;
+    
+	protected int mode;
+	protected float dist;
+	
+	public ConstraintDefinitionDistLimit(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+		mode = ((Number) constraintData.getFieldValue("mode")).intValue();
+		dist = ((Number) constraintData.getFieldValue("dist")).floatValue();
+	}
+	
+	@Override
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
+		Vector3f v = ownerTransform.getTranslation().subtract(targetTransform.getTranslation());
+		float currentDistance = v.length();
+		
+		switch (mode) {
+			case LIMITDIST_INSIDE:
+				if (currentDistance >= dist) {
+					v.normalizeLocal();
+					v.multLocal(dist + (currentDistance - dist) * (1.0f - influence));
+					ownerTransform.getTranslation().set(v.addLocal(targetTransform.getTranslation()));
+				}
+				break;
+			case LIMITDIST_ONSURFACE:
+				if (currentDistance > dist) {
+					v.normalizeLocal();
+					v.multLocal(dist + (currentDistance - dist) * (1.0f - influence));
+					ownerTransform.getTranslation().set(v.addLocal(targetTransform.getTranslation()));
+				} else if(currentDistance < dist) {
+					v.normalizeLocal().multLocal(dist * influence);
+					ownerTransform.getTranslation().set(targetTransform.getTranslation().add(v));
+				}
+				break;
+			case LIMITDIST_OUTSIDE:
+				if (currentDistance <= dist) {
+					v = targetTransform.getTranslation().subtract(ownerTransform.getTranslation()).normalizeLocal().multLocal(dist * influence);
+					ownerTransform.getTranslation().set(targetTransform.getTranslation().add(v));
+				}
+				break;
+			default:
+				throw new IllegalStateException("Unknown distance limit constraint mode: " + mode);
+		}
+	}
+}

+ 83 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionFactory.java

@@ -0,0 +1,83 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+public class ConstraintDefinitionFactory {
+	private static final Map<String, Class<? extends ConstraintDefinition>> CONSTRAINT_CLASSES = new HashMap<String, Class<? extends ConstraintDefinition>>();
+	static {
+		CONSTRAINT_CLASSES.put("bActionConstraint", ConstraintDefinitionAction.class);
+		CONSTRAINT_CLASSES.put("bChildOfConstraint", ConstraintDefinitionChildOf.class);
+		CONSTRAINT_CLASSES.put("bClampToConstraint", ConstraintDefinitionClampTo.class);
+		CONSTRAINT_CLASSES.put("bDistLimitConstraint", ConstraintDefinitionDistLimit.class);
+		CONSTRAINT_CLASSES.put("bFollowPathConstraint", ConstraintDefinitionFollowPath.class);
+		CONSTRAINT_CLASSES.put("bKinematicConstraint", ConstraintDefinitionInverseKinematics.class);
+		CONSTRAINT_CLASSES.put("bLockTrackConstraint", ConstraintDefinitionLockTrack.class);
+		CONSTRAINT_CLASSES.put("bLocateLikeConstraint", ConstraintDefinitionLocLike.class);
+		CONSTRAINT_CLASSES.put("bLocLimitConstraint", ConstraintDefinitionLocLimit.class);
+		CONSTRAINT_CLASSES.put("bMinMaxConstraint", ConstraintDefinitionMinMax.class);
+		CONSTRAINT_CLASSES.put("bNullConstraint", ConstraintDefinitionNull.class);
+		CONSTRAINT_CLASSES.put("bPythonConstraint", ConstraintDefinitionPython.class);
+		CONSTRAINT_CLASSES.put("bRigidBodyJointConstraint", ConstraintDefinitionRigidBodyJoint.class);
+		CONSTRAINT_CLASSES.put("bRotateLikeConstraint", ConstraintDefinitionRotLike.class);
+		CONSTRAINT_CLASSES.put("bShrinkWrapConstraint", ConstraintDefinitionShrinkWrap.class);
+		CONSTRAINT_CLASSES.put("bSizeLikeConstraint", ConstraintDefinitionSizeLike.class);
+		CONSTRAINT_CLASSES.put("bSizeLimitConstraint", ConstraintDefinitionSizeLimit.class);
+		CONSTRAINT_CLASSES.put("bStretchToConstraint", ConstraintDefinitionStretchTo.class);
+		CONSTRAINT_CLASSES.put("bTransformConstraint", ConstraintDefinitionTransform.class);
+		CONSTRAINT_CLASSES.put("bRotLimitConstraint", ConstraintDefinitionRotLimit.class);
+		//Blender 2.50+
+		CONSTRAINT_CLASSES.put("bSplineIKConstraint", ConstraintDefinitionSplineInverseKinematic.class);
+		CONSTRAINT_CLASSES.put("bDampTrackConstraint", ConstraintDefinitionDampTrack.class);
+		CONSTRAINT_CLASSES.put("bPivotConstraint", ConstraintDefinitionDampTrack.class);
+		//Blender 2.56+
+		CONSTRAINT_CLASSES.put("bTrackToConstraint", ConstraintDefinitionTrackTo.class);
+		CONSTRAINT_CLASSES.put("bSameVolumeConstraint", ConstraintDefinitionSameVolume.class);
+		CONSTRAINT_CLASSES.put("bTransLikeConstraint", ConstraintDefinitionTransLike.class);
+	}
+	
+	/**
+	 * This method creates the constraint instance.
+	 * 
+	 * @param constraintStructure
+	 *            the constraint's structure (bConstraint clss in blender 2.49). If the value is null the NullConstraint is created.
+	 * @param ownerOMA
+	 *            the old memory address of the constraint's owner
+	 * @param influenceIpo
+	 *            the ipo curve of the influence factor
+	 * @param blenderContext
+	 *            the blender context
+	 * @throws BlenderFileException
+	 *             this exception is thrown when the blender file is somehow
+	 *             corrupted
+	 */
+	public static ConstraintDefinition createConstraintDefinition(Structure constraintStructure, BlenderContext blenderContext) throws BlenderFileException {
+		if(constraintStructure == null) {
+			return new ConstraintDefinitionNull(null, blenderContext);
+		}
+		String constraintClassName = constraintStructure.getType();
+		Class<? extends ConstraintDefinition> constraintDefinitionClass = CONSTRAINT_CLASSES.get(constraintClassName);
+		if(constraintDefinitionClass != null) {
+			try {
+				return (ConstraintDefinition) constraintDefinitionClass.getDeclaredConstructors()[0].newInstance(constraintStructure, blenderContext);
+			} catch (IllegalArgumentException e) {
+				throw new BlenderFileException(e.getLocalizedMessage(), e);
+			} catch (SecurityException e) {
+				throw new BlenderFileException(e.getLocalizedMessage(), e);
+			} catch (InstantiationException e) {
+				throw new BlenderFileException(e.getLocalizedMessage(), e);
+			} catch (IllegalAccessException e) {
+				throw new BlenderFileException(e.getLocalizedMessage(), e);
+			} catch (InvocationTargetException e) {
+				throw new BlenderFileException(e.getLocalizedMessage(), e);
+			}
+		} else {
+			throw new BlenderFileException("Unknown constraint type: " + constraintClassName);
+		}
+	}
+}

+ 26 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionFollowPath.java

@@ -0,0 +1,26 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.jme3.math.Transform;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * This class represents 'Follow path' constraint type in blender.
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class ConstraintDefinitionFollowPath extends ConstraintDefinition {
+	private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionFollowPath.class.getName());
+	
+	public ConstraintDefinitionFollowPath(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+	}
+	
+	@Override
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
+		//TODO: implement when curves are implemented
+		LOGGER.log(Level.INFO, "'Follow path' not implemented! Curves not yet implemented!");
+	}
+}

+ 8 - 26
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintInverseKinematics.java → engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionInverseKinematics.java

@@ -1,44 +1,26 @@
-package com.jme3.scene.plugins.blender.constraints;
+package com.jme3.scene.plugins.blender.constraints.definitions;
 
 import com.jme3.animation.Animation;
 import com.jme3.animation.Skeleton;
+import com.jme3.math.Transform;
 import com.jme3.scene.plugins.blender.BlenderContext;
 import com.jme3.scene.plugins.blender.animations.CalculationBone;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
 import com.jme3.scene.plugins.blender.file.Structure;
-import java.util.logging.Logger;
 
 /**
  * This class represents 'Inverse kinematics' constraint type in blender.
  * @author Marcin Roguski (Kaelthas)
  */
-/*package*/ class ConstraintInverseKinematics extends Constraint {
-	private static final Logger LOGGER = Logger.getLogger(ConstraintInverseKinematics.class.getName());
-	private static final float IK_SOLVER_ERROR = 0.5f;
+/*package*/ class ConstraintDefinitionInverseKinematics extends ConstraintDefinition {
+	//private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionInverseKinematics.class.getName());
+	//private static final float IK_SOLVER_ERROR = 0.5f;
 	
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintInverseKinematics(Structure constraintStructure,
-			Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
+	public ConstraintDefinitionInverseKinematics(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
 	}
 
 	@Override
-	protected void bakeConstraint() {
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
 //		try {
 			// IK solver is only attached to bones
 //			Bone ownerBone = (Bone) blenderContext.getLoadedFeature(ownerOMA, LoadedFeatureDataType.LOADED_FEATURE);

+ 74 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionLocLike.java

@@ -0,0 +1,74 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import com.jme3.math.Transform;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * This class represents 'Loc like' constraint type in blender.
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class ConstraintDefinitionLocLike extends ConstraintDefinition {
+	private static final int LOCLIKE_X = 0x01;
+	private static final int LOCLIKE_Y = 0x02;
+	private static final int LOCLIKE_Z = 0x04;
+    //protected static final int LOCLIKE_TIP = 0x08;//this is deprecated in blender
+    private static final int LOCLIKE_X_INVERT = 0x10;
+    private static final int LOCLIKE_Y_INVERT = 0x20;
+    private static final int LOCLIKE_Z_INVERT = 0x40;
+    private static final int LOCLIKE_OFFSET = 0x80;
+    
+    public ConstraintDefinitionLocLike(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+		if(blenderContext.getBlenderKey().isFixUpAxis()) {
+			//swapping Y and X limits flag in the bitwise flag
+			int y = flag & LOCLIKE_Y;
+			int invY = flag & LOCLIKE_Y_INVERT;
+			int z = flag & LOCLIKE_Z;
+			int invZ = flag & LOCLIKE_Z_INVERT;
+			flag &= LOCLIKE_X | LOCLIKE_X_INVERT | LOCLIKE_OFFSET;//clear the other flags to swap them
+			flag |= y << 1;
+			flag |= invY << 1;
+			flag |= z >> 1;
+			flag |= invZ >> 1;
+		}
+	}
+    
+	@Override
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
+		Vector3f ownerLocation = ownerTransform.getTranslation();
+		Vector3f targetLocation = targetTransform.getTranslation();
+		
+		Vector3f startLocation = ownerTransform.getTranslation().clone();
+		Vector3f offset = Vector3f.ZERO;
+		if ((flag & LOCLIKE_OFFSET) != 0) {//we add the original location to the copied location
+			offset = startLocation;
+		}
+
+		if ((flag & LOCLIKE_X) != 0) {
+			ownerLocation.x = targetLocation.x;
+			if ((flag & LOCLIKE_X_INVERT) != 0) {
+				ownerLocation.x = -ownerLocation.x;
+			}
+		}
+		if ((flag & LOCLIKE_Y) != 0) {
+			ownerLocation.y = targetLocation.y;
+			if ((flag & LOCLIKE_Y_INVERT) != 0) {
+				ownerLocation.y = -ownerLocation.y;
+			}
+		}
+		if ((flag & LOCLIKE_Z) != 0) {
+			ownerLocation.z = targetLocation.z;
+			if ((flag & LOCLIKE_Z_INVERT) != 0) {
+				ownerLocation.z = -ownerLocation.z;
+			}
+		}
+		ownerLocation.addLocal(offset);
+		
+		if(influence < 1.0f) {
+			startLocation.subtractLocal(ownerLocation).normalizeLocal().mult(influence);
+			ownerLocation.addLocal(startLocation);
+		}
+	}
+}

+ 87 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionLocLimit.java

@@ -0,0 +1,87 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import com.jme3.math.Transform;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * This class represents 'Loc limit' constraint type in blender.
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class ConstraintDefinitionLocLimit extends ConstraintDefinition {
+	private static final int LIMIT_XMIN = 0x01;
+    private static final int LIMIT_XMAX = 0x02;
+    private static final int LIMIT_YMIN = 0x04;
+    private static final int LIMIT_YMAX = 0x08;
+    private static final int LIMIT_ZMIN = 0x10;
+    private static final int LIMIT_ZMAX = 0x20;
+    
+    protected float[][] limits = new float[3][2];
+    
+    public ConstraintDefinitionLocLimit(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+		if(blenderContext.getBlenderKey().isFixUpAxis()) {
+			limits[0][0] = ((Number) constraintData.getFieldValue("xmin")).floatValue();
+			limits[0][1] = ((Number) constraintData.getFieldValue("xmax")).floatValue();
+			limits[2][0] = -((Number) constraintData.getFieldValue("ymin")).floatValue();
+			limits[2][1] = -((Number) constraintData.getFieldValue("ymax")).floatValue();
+			limits[1][0] = ((Number) constraintData.getFieldValue("zmin")).floatValue();
+			limits[1][1] = ((Number) constraintData.getFieldValue("zmax")).floatValue();
+			
+			//swapping Y and X limits flag in the bitwise flag
+			int ymin = flag & LIMIT_YMIN;
+			int ymax = flag & LIMIT_YMAX;
+			int zmin = flag & LIMIT_ZMIN;
+			int zmax = flag & LIMIT_ZMAX;
+			flag &= LIMIT_XMIN | LIMIT_XMAX;//clear the other flags to swap them
+			flag |= ymin << 2;
+			flag |= ymax << 2;
+			flag |= zmin >> 2;
+			flag |= zmax >> 2;
+		} else {
+			limits[0][0] = ((Number) constraintData.getFieldValue("xmin")).floatValue();
+			limits[0][1] = ((Number) constraintData.getFieldValue("xmax")).floatValue();
+			limits[1][0] = ((Number) constraintData.getFieldValue("ymin")).floatValue();
+			limits[1][1] = ((Number) constraintData.getFieldValue("ymax")).floatValue();
+			limits[2][0] = ((Number) constraintData.getFieldValue("zmin")).floatValue();
+			limits[2][1] = ((Number) constraintData.getFieldValue("zmax")).floatValue();
+		}
+	}
+	
+	@Override
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
+		Vector3f translation = ownerTransform.getTranslation();
+		
+		if ((flag & LIMIT_XMIN) != 0) {
+			if (translation.x < limits[0][0]) {
+				translation.x -= (translation.x - limits[0][0]) * influence;
+			}
+		}
+		if ((flag & LIMIT_XMAX) != 0) {
+			if (translation.x > limits[0][1]) {
+				translation.x -= (translation.x - limits[0][1]) * influence;
+			}
+		}
+		if ((flag & LIMIT_YMIN) != 0) {
+			if (translation.y < limits[1][0]) {
+				translation.y -= (translation.y - limits[1][0]) * influence;
+			}
+		}
+		if ((flag & LIMIT_YMAX) != 0) {
+			if (translation.y > limits[1][1]) {
+				translation.y -= (translation.y - limits[1][1]) * influence;
+			}
+		}
+		if ((flag & LIMIT_ZMIN) != 0) {
+			if (translation.z < limits[2][0]) {
+				translation.z -= (translation.z - limits[2][0]) * influence;
+			}
+		}
+		if ((flag & LIMIT_ZMAX) != 0) {
+			if (translation.z > limits[2][1]) {
+				translation.z -= (translation.z - limits[2][1]) * influence;
+			}
+		}
+	}
+}

+ 26 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionLockTrack.java

@@ -0,0 +1,26 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.jme3.math.Transform;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * This class represents 'Action' constraint type in blender.
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class ConstraintDefinitionLockTrack extends ConstraintDefinition {
+	private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionLockTrack.class.getName());
+	
+	public ConstraintDefinitionLockTrack(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+	}
+	
+	@Override
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
+		// TODO: implement 'Lock track' constraint
+		LOGGER.log(Level.WARNING, "'Lock track' constraint NOT implemented!");
+	}
+}

+ 26 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionMinMax.java

@@ -0,0 +1,26 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.jme3.math.Transform;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * This class represents 'Min max' constraint type in blender.
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class ConstraintDefinitionMinMax extends ConstraintDefinition {
+	private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionMinMax.class.getName());
+	
+	public ConstraintDefinitionMinMax(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+	}
+	
+	@Override
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
+		// TODO: implement 'Min max' constraint
+		LOGGER.log(Level.WARNING, "'Min max' constraint NOT implemented!");
+	}
+}

+ 19 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionNull.java

@@ -0,0 +1,19 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import com.jme3.math.Transform;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * This class represents 'Null' constraint type in blender.
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class ConstraintDefinitionNull extends ConstraintDefinition {
+
+	public ConstraintDefinitionNull(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+	}
+	
+	@Override
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) { }
+}

+ 26 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionPivot.java

@@ -0,0 +1,26 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.jme3.math.Transform;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * The pivot constraint. Available for blender 2.50+.
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class ConstraintDefinitionPivot extends ConstraintDefinition {
+	private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionPivot.class.getName());
+	
+	public ConstraintDefinitionPivot(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+	}
+	
+	@Override
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
+		// TODO: implement 'Pivot' constraint
+		LOGGER.log(Level.WARNING, "'Pivot' constraint NOT implemented!");
+	}
+}

+ 26 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionPython.java

@@ -0,0 +1,26 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.jme3.math.Transform;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * This class represents 'Python' constraint type in blender.
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class ConstraintDefinitionPython extends ConstraintDefinition {
+	private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionPython.class.getName());
+	
+	public ConstraintDefinitionPython(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+	}
+	
+	@Override
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
+		// TODO: implement 'Python' constraint
+		LOGGER.log(Level.WARNING, "'Python' constraint NOT implemented!");
+	}
+}

+ 26 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionRigidBodyJoint.java

@@ -0,0 +1,26 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.jme3.math.Transform;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * This class represents 'Rigid body joint' constraint type in blender.
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class ConstraintDefinitionRigidBodyJoint extends ConstraintDefinition {
+	private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionRigidBodyJoint.class.getName());
+	
+	public ConstraintDefinitionRigidBodyJoint(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+	}
+	
+	@Override
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
+		// TODO: implement 'Rigid body joint' constraint
+		LOGGER.log(Level.WARNING, "'Rigid body joint' constraint NOT implemented!");
+	}
+}

+ 67 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionRotLike.java

@@ -0,0 +1,67 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import com.jme3.math.Quaternion;
+import com.jme3.math.Transform;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * This class represents 'Rot like' constraint type in blender.
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class ConstraintDefinitionRotLike extends ConstraintDefinition {
+	private static final int ROTLIKE_X = 0x01;
+	private static final int ROTLIKE_Y = 0x02;
+	private static final int ROTLIKE_Z = 0x04;
+	private static final int ROTLIKE_X_INVERT = 0x10;
+    private static final int ROTLIKE_Y_INVERT = 0x20;
+    private static final int ROTLIKE_Z_INVERT = 0x40;
+    private static final int ROTLIKE_OFFSET = 0x80;
+    
+    private transient float[] ownerAngles = new float[3];
+    private transient float[] targetAngles = new float[3];
+    
+    public ConstraintDefinitionRotLike(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+	}
+
+    @Override
+    public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
+    	Quaternion ownerRotation = ownerTransform.getRotation();    	
+    	ownerAngles = ownerRotation.toAngles(ownerAngles);
+    	targetAngles = targetTransform.getRotation().toAngles(targetAngles);
+    	
+    	Quaternion startRotation = ownerRotation.clone();
+		Quaternion offset = Quaternion.IDENTITY;
+		if ((flag & ROTLIKE_OFFSET) != 0) {//we add the original rotation to the copied rotation
+			offset = startRotation;
+		}
+
+		if ((flag & ROTLIKE_X) != 0) {
+			ownerAngles[0] = targetAngles[0];
+			if ((flag & ROTLIKE_X_INVERT) != 0) {
+				ownerAngles[0] = -ownerAngles[0];
+			}
+		}
+		if ((flag & ROTLIKE_Y) != 0) {
+			ownerAngles[1] = targetAngles[1];
+			if ((flag & ROTLIKE_Y_INVERT) != 0) {
+				ownerAngles[1] = -ownerAngles[1];
+			}
+		}
+		if ((flag & ROTLIKE_Z) != 0) {
+			ownerAngles[2] = targetAngles[2];
+			if ((flag & ROTLIKE_Z_INVERT) != 0) {
+				ownerAngles[2] = -ownerAngles[2];
+			}
+		}
+		ownerRotation.fromAngles(ownerAngles).multLocal(offset);
+
+		if(influence < 1.0f) {
+			
+//			startLocation.subtractLocal(ownerLocation).normalizeLocal().mult(influence);
+//			ownerLocation.addLocal(startLocation);
+			//TODO
+		}
+    }
+}

+ 85 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionRotLimit.java

@@ -0,0 +1,85 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import com.jme3.math.FastMath;
+import com.jme3.math.Transform;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * This class represents 'Rot limit' constraint type in blender.
+ * 
+ * @author Marcin Roguski (Kaelthas)
+ */
+/* package */class ConstraintDefinitionRotLimit extends ConstraintDefinition {
+	private static final int	LIMIT_XROT	= 0x01;
+	private static final int	LIMIT_YROT	= 0x02;
+	private static final int	LIMIT_ZROT	= 0x04;
+
+	private float[][]			limits		= new float[3][2];
+	private transient float[]	angles 		= new float[3];
+	
+	public ConstraintDefinitionRotLimit(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+		if (blenderContext.getBlenderKey().isFixUpAxis()/* && owner.spatial != null*/) {//FIXME: !!!!!!!!
+			limits[0][0] = ((Number) constraintData.getFieldValue("xmin")).floatValue();
+			limits[0][1] = ((Number) constraintData.getFieldValue("xmax")).floatValue();
+			limits[2][0] = -((Number) constraintData.getFieldValue("ymin")).floatValue();
+			limits[2][1] = -((Number) constraintData.getFieldValue("ymax")).floatValue();
+			limits[1][0] = ((Number) constraintData.getFieldValue("zmin")).floatValue();
+			limits[1][1] = ((Number) constraintData.getFieldValue("zmax")).floatValue();
+
+			// swapping Y and X limits flag in the bitwise flag
+			int limitY = flag & LIMIT_YROT;
+			int limitZ = flag & LIMIT_ZROT;
+			flag &= LIMIT_XROT;// clear the other flags to swap them
+			flag |= limitY << 1;
+			flag |= limitZ >> 1;
+		} else {
+			limits[0][0] = ((Number) constraintData.getFieldValue("xmin")).floatValue();
+			limits[0][1] = ((Number) constraintData.getFieldValue("xmax")).floatValue();
+			limits[1][0] = ((Number) constraintData.getFieldValue("ymin")).floatValue();
+			limits[1][1] = ((Number) constraintData.getFieldValue("ymax")).floatValue();
+			limits[2][0] = ((Number) constraintData.getFieldValue("zmin")).floatValue();
+			limits[2][1] = ((Number) constraintData.getFieldValue("zmax")).floatValue();
+		}
+
+		// until blender 2.49 the rotations values were stored in degrees
+		if (blenderContext.getBlenderVersion() <= 249) {
+			for (int i = 0; i < limits.length; ++i) {
+				limits[i][0] *= FastMath.DEG_TO_RAD;
+				limits[i][1] *= FastMath.DEG_TO_RAD;
+			}
+		}
+	}
+	
+	@Override
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
+		if ((flag & LIMIT_XROT) != 0) {
+			float difference = 0.0f;
+			if (angles[0] < limits[0][0]) {
+				difference = (angles[0] - limits[0][0]) * influence;
+			} else if (angles[0] > limits[0][1]) {
+				difference = (angles[0] - limits[0][1]) * influence;
+			}
+			angles[0] -= difference;
+		}
+		if ((flag & LIMIT_YROT) != 0) {
+			float difference = 0.0f;
+			if (angles[1] < limits[1][0]) {
+				difference = (angles[1] - limits[1][0]) * influence;
+			} else if (angles[1] > limits[1][1]) {
+				difference = (angles[1] - limits[1][1]) * influence;
+			}
+			angles[1] -= difference;
+		}
+		if ((flag & LIMIT_ZROT) != 0) {
+			float difference = 0.0f;
+			if (angles[2] < limits[2][0]) {
+				difference = (angles[2] - limits[2][0]) * influence;
+			} else if (angles[2] > limits[2][1]) {
+				difference = (angles[2] - limits[2][1]) * influence;
+			}
+			angles[2] -= difference;
+		}
+	}
+}

+ 27 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionSameVolume.java

@@ -0,0 +1,27 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.jme3.math.Transform;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * This class represents 'Same volume' constraint type in blender.
+ * 
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class ConstraintDefinitionSameVolume extends ConstraintDefinition {
+	private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionSameVolume.class.getName());
+	
+	public ConstraintDefinitionSameVolume(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+	}
+	
+	@Override
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
+		// TODO: implement 'Same volume' constraint
+		LOGGER.log(Level.WARNING, "'Same volume' constraint NOT implemented!");
+	}
+}

+ 8 - 37
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintShrinkWrap.java → engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionShrinkWrap.java

@@ -1,52 +1,23 @@
-package com.jme3.scene.plugins.blender.constraints;
+package com.jme3.scene.plugins.blender.constraints.definitions;
 
-import com.jme3.animation.Animation;
-import com.jme3.math.Quaternion;
-import com.jme3.math.Vector3f;
-import com.jme3.scene.Geometry;
-import com.jme3.scene.Mesh;
-import com.jme3.scene.Node;
-import com.jme3.scene.Spatial;
-import com.jme3.scene.VertexBuffer.Type;
+import com.jme3.math.Transform;
 import com.jme3.scene.plugins.blender.BlenderContext;
-import com.jme3.scene.plugins.blender.animations.Ipo;
-import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
 import com.jme3.scene.plugins.blender.file.Structure;
-import com.jme3.scene.plugins.ogre.AnimData;
-import java.nio.FloatBuffer;
-import java.util.ArrayList;
-import java.util.List;
 
 /**
  * This class represents 'Shrink wrap' constraint type in blender.
  * @author Marcin Roguski (Kaelthas)
  */
-/*package*/ class ConstraintShrinkWrap extends Constraint {
+/*package*/ class ConstraintDefinitionShrinkWrap extends ConstraintDefinition {
 	
-	/**
-	 * This constructor creates the constraint instance.
-	 * 
-	 * @param constraintStructure
-	 *            the constraint's structure (bConstraint clss in blender 2.49).
-	 * @param ownerOMA
-	 *            the old memory address of the constraint owner
-	 * @param influenceIpo
-	 *            the ipo curve of the influence factor
-	 * @param blenderContext
-	 *            the blender context
-	 * @throws BlenderFileException
-	 *             this exception is thrown when the blender file is somehow
-	 *             corrupted
-	 */
-	public ConstraintShrinkWrap(Structure constraintStructure, Long ownerOMA,
-			Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
-		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
+	public ConstraintDefinitionShrinkWrap(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
 	}
 
 	@Override
-	protected void bakeConstraint() {
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
 		//loading mesh points (blender ensures that the target is a mesh-object)
-		List<Vector3f> pts = new ArrayList<Vector3f>();
+		/*List<Vector3f> pts = new ArrayList<Vector3f>();
 		Node target = (Node) this.target.getObject();
 		for(Spatial spatial : target.getChildren()) {
 			if(spatial instanceof Geometry) {
@@ -84,7 +55,7 @@ import java.util.List;
 				
 				track.setKeyframes(track.getTimes(), translations, rotations, track.getScales());
 			}
-		}
+		}*/
 		
 		//TODO: static constraint for spatials
 	}

+ 51 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionSizeLike.java

@@ -0,0 +1,51 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import com.jme3.math.Transform;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * This class represents 'Size like' constraint type in blender.
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class ConstraintDefinitionSizeLike extends ConstraintDefinition {
+	private static final int SIZELIKE_X = 0x01;
+	private static final int SIZELIKE_Y = 0x02;
+	private static final int SIZELIKE_Z = 0x04;
+	private static final int LOCLIKE_OFFSET = 0x80;
+    
+	public ConstraintDefinitionSizeLike(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+		if(blenderContext.getBlenderKey().isFixUpAxis()) {
+			//swapping Y and X limits flag in the bitwise flag
+			int y = flag & SIZELIKE_Y;
+			int z = flag & SIZELIKE_Z;
+			flag &= SIZELIKE_X | LOCLIKE_OFFSET;//clear the other flags to swap them
+			flag |= y << 1;
+			flag |= z >> 1;
+		}
+	}
+	
+	@Override
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
+		Vector3f ownerScale = ownerTransform.getScale();
+		Vector3f targetScale = targetTransform.getScale();
+		
+		Vector3f offset = Vector3f.ZERO;
+		if ((flag & LOCLIKE_OFFSET) != 0) {//we add the original scale to the copied scale
+			offset = ownerScale.clone();
+		}
+
+		if ((flag & SIZELIKE_X) != 0) {
+			ownerScale.x = targetScale.x * influence + (1.0f - influence) * ownerScale.x;
+		}
+		if ((flag & SIZELIKE_Y) != 0) {
+			ownerScale.y = targetScale.y * influence + (1.0f - influence) * ownerScale.y;
+		}
+		if ((flag & SIZELIKE_Z) != 0) {
+			ownerScale.z = targetScale.z * influence + (1.0f - influence) * ownerScale.z;
+		}
+		ownerScale.addLocal(offset);
+	}
+}

+ 75 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionSizeLimit.java

@@ -0,0 +1,75 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import com.jme3.math.Transform;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * This class represents 'Size limit' constraint type in blender.
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class ConstraintDefinitionSizeLimit extends ConstraintDefinition {
+	private static final int LIMIT_XMIN = 0x01;
+	private static final int LIMIT_XMAX = 0x02;
+	private static final int LIMIT_YMIN = 0x04;
+	private static final int LIMIT_YMAX = 0x08;
+	private static final int LIMIT_ZMIN = 0x10;
+	private static final int LIMIT_ZMAX = 0x20;
+	
+	protected float[][] limits = new float[3][2];
+	
+	public ConstraintDefinitionSizeLimit(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+		if(blenderContext.getBlenderKey().isFixUpAxis()) {
+			limits[0][0] = ((Number) constraintData.getFieldValue("xmin")).floatValue();
+			limits[0][1] = ((Number) constraintData.getFieldValue("xmax")).floatValue();
+			limits[2][0] = -((Number) constraintData.getFieldValue("ymin")).floatValue();
+			limits[2][1] = -((Number) constraintData.getFieldValue("ymax")).floatValue();
+			limits[1][0] = ((Number) constraintData.getFieldValue("zmin")).floatValue();
+			limits[1][1] = ((Number) constraintData.getFieldValue("zmax")).floatValue();
+			
+			//swapping Y and X limits flag in the bitwise flag
+			int ymin = flag & LIMIT_YMIN;
+			int ymax = flag & LIMIT_YMAX;
+			int zmin = flag & LIMIT_ZMIN;
+			int zmax = flag & LIMIT_ZMAX;
+			flag &= LIMIT_XMIN | LIMIT_XMAX;//clear the other flags to swap them
+			flag |= ymin << 2;
+			flag |= ymax << 2;
+			flag |= zmin >> 2;
+			flag |= zmax >> 2;
+		} else {
+			limits[0][0] = ((Number) constraintData.getFieldValue("xmin")).floatValue();
+			limits[0][1] = ((Number) constraintData.getFieldValue("xmax")).floatValue();
+			limits[1][0] = ((Number) constraintData.getFieldValue("ymin")).floatValue();
+			limits[1][1] = ((Number) constraintData.getFieldValue("ymax")).floatValue();
+			limits[2][0] = ((Number) constraintData.getFieldValue("zmin")).floatValue();
+			limits[2][1] = ((Number) constraintData.getFieldValue("zmax")).floatValue();
+		}
+	}
+	
+	@Override
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
+		Vector3f scale = ownerTransform.getScale();
+		
+		if ((flag & LIMIT_XMIN) != 0 && scale.x < limits[0][0]) {
+			scale.x -= (scale.x - limits[0][0]) * influence;
+		}
+		if ((flag & LIMIT_XMAX) != 0 && scale.x > limits[0][1]) {
+			scale.x -= (scale.x - limits[0][1]) * influence;
+		}
+		if ((flag & LIMIT_YMIN) != 0 && scale.y < limits[1][0]) {
+			scale.y -= (scale.y - limits[1][0]) * influence;
+		}
+		if ((flag & LIMIT_YMAX) != 0 && scale.y > limits[1][1]) {
+			scale.y -= (scale.y - limits[1][1]) * influence;
+		}
+		if ((flag & LIMIT_ZMIN) != 0 && scale.z < limits[2][0]) {
+			scale.z -= (scale.z - limits[2][0]) * influence;
+		}
+		if ((flag & LIMIT_ZMAX) != 0 && scale.z > limits[2][1]) {
+			scale.z -= (scale.z - limits[2][1]) * influence;
+		}
+	}
+}

+ 26 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionSplineInverseKinematic.java

@@ -0,0 +1,26 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.jme3.math.Transform;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * The spline inverse kinematic constraint. Available for blender 2.50+.
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class ConstraintDefinitionSplineInverseKinematic extends ConstraintDefinition {
+	private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionSplineInverseKinematic.class.getName());
+	
+	public ConstraintDefinitionSplineInverseKinematic(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+	}
+	
+	@Override
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
+		// TODO Auto-generated method stub
+		LOGGER.log(Level.WARNING, "'Splie IK' constraint NOT implemented!");		
+	}
+}

+ 26 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionStretchTo.java

@@ -0,0 +1,26 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.jme3.math.Transform;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * This class represents 'Stretch to' constraint type in blender.
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class ConstraintDefinitionStretchTo extends ConstraintDefinition {
+	private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionStretchTo.class.getName());
+	
+	public ConstraintDefinitionStretchTo(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+	}
+
+	@Override
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
+		// TODO: implement 'Stretch to' constraint
+		LOGGER.log(Level.WARNING, "'Stretch to' constraint NOT implemented!");
+	}
+}

+ 27 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionTrackTo.java

@@ -0,0 +1,27 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.jme3.math.Transform;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * This class represents 'Track to' constraint type in blender.
+ * 
+ * @author Marcin Roguski (Kaelthas)
+ */
+/* package */class ConstraintDefinitionTrackTo extends ConstraintDefinition {
+	private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionTrackTo.class.getName());
+
+	public ConstraintDefinitionTrackTo(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+	}
+	
+	@Override
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
+		// TODO: implement 'Track to' constraint
+		LOGGER.log(Level.WARNING, "'Track to' constraint NOT implemented!");
+	}
+}

+ 27 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionTransLike.java

@@ -0,0 +1,27 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.jme3.math.Transform;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * This class represents 'Trans like' constraint type in blender.
+ * 
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class ConstraintDefinitionTransLike extends ConstraintDefinition {
+	private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionTransLike.class.getName());
+	
+	public ConstraintDefinitionTransLike(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+	}
+	
+	@Override
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
+		// TODO: implement 'Trans like' constraint
+		LOGGER.log(Level.WARNING, "'Trans like' constraint NOT implemented!");
+	}
+}

+ 26 - 0
engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionTransform.java

@@ -0,0 +1,26 @@
+package com.jme3.scene.plugins.blender.constraints.definitions;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.jme3.math.Transform;
+import com.jme3.scene.plugins.blender.BlenderContext;
+import com.jme3.scene.plugins.blender.file.Structure;
+
+/**
+ * This class represents 'Transform' constraint type in blender.
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ class ConstraintDefinitionTransform extends ConstraintDefinition {
+	private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionAction.class.getName());
+	
+	public ConstraintDefinitionTransform(Structure constraintData, BlenderContext blenderContext) {
+		super(constraintData, blenderContext);
+	}
+
+	@Override
+	public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
+		// TODO: implement 'Transform' constraint
+		LOGGER.log(Level.WARNING, "'Transform' constraint NOT implemented!");
+	}
+}

+ 0 - 13
engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ArmatureModifier.java

@@ -26,7 +26,6 @@ import com.jme3.scene.VertexBuffer.Usage;
 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.constraints.Constraint;
 import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
 import com.jme3.scene.plugins.blender.file.FileBlockHeader;
 import com.jme3.scene.plugins.blender.file.Pointer;
@@ -224,18 +223,6 @@ import com.jme3.util.BufferUtils;
 			}
 		}
 
-		// applying constraints to Bones
-		ArmatureHelper armatureHelper = blenderContext.getHelper(ArmatureHelper.class);
-		for (int i = 0; i < animData.skeleton.getBoneCount(); ++i) {
-			Long boneOMA = armatureHelper.getBoneOMA(animData.skeleton.getBone(i));
-			List<Constraint> constraints = blenderContext.getConstraints(boneOMA);
-			if (constraints != null && constraints.size() > 0) {
-				for (Constraint constraint : constraints) {
-					constraint.bake();
-				}
-			}
-		}
-
 		// applying animations
 		AnimControl control = new AnimControl(animData.skeleton);
 		ArrayList<Animation> animList = animData.anims;

+ 0 - 9
engine/src/blender/com/jme3/scene/plugins/blender/objects/ObjectHelper.java

@@ -51,7 +51,6 @@ import com.jme3.scene.plugins.blender.AbstractBlenderHelper;
 import com.jme3.scene.plugins.blender.BlenderContext;
 import com.jme3.scene.plugins.blender.BlenderContext.LoadedFeatureDataType;
 import com.jme3.scene.plugins.blender.cameras.CameraHelper;
-import com.jme3.scene.plugins.blender.constraints.Constraint;
 import com.jme3.scene.plugins.blender.constraints.ConstraintHelper;
 import com.jme3.scene.plugins.blender.curves.CurvesHelper;
 import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
@@ -238,14 +237,6 @@ public class ObjectHelper extends AbstractBlenderHelper {
 			ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class);
 			constraintHelper.loadConstraints(objectStructure, blenderContext);
 			
-			//baking constraints
-			List<Constraint> objectConstraints = blenderContext.getConstraints(objectStructure.getOldMemoryAddress());
-			if(objectConstraints!=null) {
-				for(Constraint objectConstraint : objectConstraints) {
-					objectConstraint.bake();
-				}
-			}
-			
 			//reading custom properties
 			if(blenderContext.getBlenderKey().isLoadObjectProperties()) {
 				Properties properties = this.loadProperties(objectStructure, blenderContext);