Fixes to limit rotation constraint.
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9125 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
c576a12f83
commit
0e9f7ea22f
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user