Parcourir la source

Fixes to limit rotation constraint.

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9125 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
Kae..pl il y a 13 ans
Parent
commit
0e9f7ea22f

+ 23 - 4
engine/src/blender/com/jme3/scene/plugins/blender/BlenderContext.java

@@ -68,6 +68,8 @@ import com.jme3.scene.plugins.ogre.AnimData;
 public class BlenderContext {
 	private static final Logger					LOGGER					= Logger.getLogger(BlenderContext.class.getName());
 
+	/** The blender file version. */
+	private int									blenderVersion;
 	/** The blender key. */
 	private BlenderKey							blenderKey;
 	/** The header of the file block. */
@@ -120,6 +122,23 @@ public class BlenderContext {
 	/** A map og helpers that perform loading. */
 	private Map<String, AbstractBlenderHelper>	helpers					= new HashMap<String, AbstractBlenderHelper>();
 
+	/**
+	 * This method sets the blender file version.
+	 * 
+	 * @param blenderVersion
+	 *            the blender file version
+	 */
+	public void setBlenderVersion(String blenderVersion) {
+		this.blenderVersion = Integer.parseInt(blenderVersion);
+	}
+
+	/**
+	 * @return the blender file version
+	 */
+	public int getBlenderVersion() {
+		return blenderVersion;
+	}
+
 	/**
 	 * This method sets the blender key.
 	 * 
@@ -496,7 +515,7 @@ public class BlenderContext {
 	public AnimData getAnimData(Long ownerOMA) {
 		return this.animData.get(ownerOMA);
 	}
-	
+
 	/**
 	 * This method sets the skeleton for the specified OMA of its owner.
 	 * 
@@ -508,7 +527,7 @@ public class BlenderContext {
 	public void setSkeleton(Long skeletonOMA, Skeleton skeleton) {
 		this.skeletons.put(skeletonOMA, skeleton);
 	}
-	
+
 	/**
 	 * This method returns the skeleton for the specified OMA of its owner.
 	 * 
@@ -544,7 +563,7 @@ public class BlenderContext {
 	public MeshContext getMeshContext(Long meshOMA) {
 		return this.meshContexts.get(meshOMA);
 	}
-	
+
 	/**
 	 * This method sets the bone context for the given bone old memory address.
 	 * If the context is already set it will be replaced.
@@ -569,7 +588,7 @@ public class BlenderContext {
 	public BoneContext getBoneContext(Long boneOMA) {
 		return boneContexts.get(boneOMA);
 	}
-	
+
 	/**
 	 * This method sets the material context for the given material. If the
 	 * context is already set it will be replaced.

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

@@ -184,6 +184,7 @@ public class BlenderLoader extends AbstractBlenderLoader {
 		blocks = new ArrayList<FileBlockHeader>();
 		FileBlockHeader fileBlock;
 		blenderContext = new BlenderContext();
+		blenderContext.setBlenderVersion(inputStream.getVersionNumber());
 		blenderContext.setAssetManager(assetInfo.getManager());
 		blenderContext.setInputStream(inputStream);
 		blenderContext.setBlenderKey(blenderKey);

+ 81 - 41
engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRotLimit.java

@@ -1,8 +1,7 @@
 package com.jme3.scene.plugins.blender.constraints;
 
-import java.util.Arrays;
-
 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;
@@ -15,16 +14,18 @@ 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;
-	
+/* 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.
 	 * 
@@ -40,58 +41,63 @@ import com.jme3.scene.plugins.ogre.AnimData;
 	 *             this exception is thrown when the blender file is somehow
 	 *             corrupted
 	 */
-	public ConstraintRotLimit(Structure constraintStructure, Long ownerOMA,
-			Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
+	public ConstraintRotLimit(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
 		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
-		
-		if(blenderContext.getBlenderKey().isFixUpAxis()) {
-			limits[0][0] = ((Number) data.getFieldValue("xmin")).floatValue() * FastMath.DEG_TO_RAD;
-			limits[0][1] = ((Number) data.getFieldValue("xmax")).floatValue() * FastMath.DEG_TO_RAD;
-			limits[2][0] = -((Number) data.getFieldValue("ymin")).floatValue() * FastMath.DEG_TO_RAD;
-			limits[2][1] = -((Number) data.getFieldValue("ymax")).floatValue() * FastMath.DEG_TO_RAD;
-			limits[1][0] = ((Number) data.getFieldValue("zmin")).floatValue() * FastMath.DEG_TO_RAD;
-			limits[1][1] = ((Number) data.getFieldValue("zmax")).floatValue() * FastMath.DEG_TO_RAD;
-		} else {
-			limits[0][0] = ((Number) data.getFieldValue("xmin")).floatValue() * FastMath.DEG_TO_RAD;
-			limits[0][1] = ((Number) data.getFieldValue("xmax")).floatValue() * FastMath.DEG_TO_RAD;
-			limits[1][0] = ((Number) data.getFieldValue("ymin")).floatValue() * FastMath.DEG_TO_RAD;
-			limits[1][1] = ((Number) data.getFieldValue("ymax")).floatValue() * FastMath.DEG_TO_RAD;
-			limits[2][0] = ((Number) data.getFieldValue("zmin")).floatValue() * FastMath.DEG_TO_RAD;
-			limits[2][1] = ((Number) data.getFieldValue("zmax")).floatValue() * FastMath.DEG_TO_RAD;
-		}
+
 		flag = ((Number) data.getFieldValue("flag")).intValue();
-		if(blenderContext.getBlenderKey().isFixUpAxis()) {
-			//swapping Y and X limits flag in the bitwise flag
+		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 &= 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) {
+		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);
-					System.out.print(Arrays.toString(angles) + "\t\t");
 					this.rotLimit(angles, ipo.calculateValue(frame));
-					System.out.println(Arrays.toString(angles));
 					rotations[frame].fromAngles(angles);
 				}
 				track.setKeyframes(track.getTimes(), track.getTranslations(), rotations, track.getScales());
 			}
 		}
-		
-		if(owner instanceof Spatial) {
+
+		if (owner instanceof Spatial) {
 			Transform ownerTransform = this.owner.getTransform();
 			float[] angles = ownerTransform.getRotation().toAngles(null);
 			this.rotLimit(angles, ipo.calculateValue(0));
@@ -99,7 +105,7 @@ import com.jme3.scene.plugins.ogre.AnimData;
 			this.owner.applyTransform(ownerTransform);
 		}
 	}
-	
+
 	/**
 	 * This method computes new constrained angles.
 	 * 
@@ -118,7 +124,7 @@ import com.jme3.scene.plugins.ogre.AnimData;
 			}
 			angles[0] -= difference;
 		}
-		if ((flag & LIMIT_ZROT) != 0) {
+		if ((flag & LIMIT_YROT) != 0) {
 			float difference = 0.0f;
 			if (angles[1] < limits[1][0]) {
 				difference = (angles[1] - limits[1][0]) * influence;
@@ -127,7 +133,7 @@ import com.jme3.scene.plugins.ogre.AnimData;
 			}
 			angles[1] -= difference;
 		}
-		/*if ((flag & LIMIT_ZROT) != 0) {
+		if ((flag & LIMIT_ZROT) != 0) {
 			float difference = 0.0f;
 			if (angles[2] < limits[2][0]) {
 				difference = (angles[2] - limits[2][0]) * influence;
@@ -135,6 +141,40 @@ import com.jme3.scene.plugins.ogre.AnimData;
 				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 - 10
engine/src/blender/com/jme3/scene/plugins/blender/constraints/Feature.java

@@ -1,7 +1,6 @@
 package com.jme3.scene.plugins.blender.constraints;
 
 import com.jme3.animation.Bone;
-import com.jme3.math.FastMath;
 import com.jme3.math.Matrix4f;
 import com.jme3.math.Quaternion;
 import com.jme3.math.Transform;
@@ -9,7 +8,6 @@ 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.BoneContext;
 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;
@@ -158,20 +156,12 @@ import com.jme3.scene.plugins.blender.file.Structure;
 			}
 		}
 		// Bone
-		BoneContext boneContext = blenderContext.getBoneContext(oma);
 		switch (space) {
 			case CONSTRAINT_SPACE_LOCAL:
 				Transform localTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation());
 				localTransform.setScale(bone.getLocalScale());
 				return localTransform;
 			case CONSTRAINT_SPACE_WORLD:
-				if(bone.getParent()!=null) {
-					System.out.println(bone.getParent().getLocalRotation());
-					System.out.println(bone.getParent().getWorldBindRotation());
-					System.out.println(bone.getParent().getModelSpaceRotation());
-					System.out.println(bone.getParent().getWorldBindInverseRotation());
-				}
-				
 				Transform worldTransform = new Transform(bone.getWorldBindPosition(), bone.getWorldBindRotation());
 				worldTransform.setScale(bone.getWorldBindScale());
 				return worldTransform;