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 {
|
public class BlenderContext {
|
||||||
private static final Logger LOGGER = Logger.getLogger(BlenderContext.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(BlenderContext.class.getName());
|
||||||
|
|
||||||
|
/** The blender file version. */
|
||||||
|
private int blenderVersion;
|
||||||
/** The blender key. */
|
/** The blender key. */
|
||||||
private BlenderKey blenderKey;
|
private BlenderKey blenderKey;
|
||||||
/** The header of the file block. */
|
/** The header of the file block. */
|
||||||
@ -120,6 +122,23 @@ public class BlenderContext {
|
|||||||
/** A map og helpers that perform loading. */
|
/** A map og helpers that perform loading. */
|
||||||
private Map<String, AbstractBlenderHelper> helpers = new HashMap<String, AbstractBlenderHelper>();
|
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.
|
* This method sets the blender key.
|
||||||
*
|
*
|
||||||
|
@ -184,6 +184,7 @@ public class BlenderLoader extends AbstractBlenderLoader {
|
|||||||
blocks = new ArrayList<FileBlockHeader>();
|
blocks = new ArrayList<FileBlockHeader>();
|
||||||
FileBlockHeader fileBlock;
|
FileBlockHeader fileBlock;
|
||||||
blenderContext = new BlenderContext();
|
blenderContext = new BlenderContext();
|
||||||
|
blenderContext.setBlenderVersion(inputStream.getVersionNumber());
|
||||||
blenderContext.setAssetManager(assetInfo.getManager());
|
blenderContext.setAssetManager(assetInfo.getManager());
|
||||||
blenderContext.setInputStream(inputStream);
|
blenderContext.setInputStream(inputStream);
|
||||||
blenderContext.setBlenderKey(blenderKey);
|
blenderContext.setBlenderKey(blenderKey);
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package com.jme3.scene.plugins.blender.constraints;
|
package com.jme3.scene.plugins.blender.constraints;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import com.jme3.animation.Animation;
|
import com.jme3.animation.Animation;
|
||||||
|
import com.jme3.animation.Bone;
|
||||||
import com.jme3.math.FastMath;
|
import com.jme3.math.FastMath;
|
||||||
import com.jme3.math.Quaternion;
|
import com.jme3.math.Quaternion;
|
||||||
import com.jme3.math.Transform;
|
import com.jme3.math.Transform;
|
||||||
@ -15,15 +14,17 @@ import com.jme3.scene.plugins.ogre.AnimData;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This class represents 'Rot limit' constraint type in blender.
|
* This class represents 'Rot limit' constraint type in blender.
|
||||||
|
*
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintRotLimit extends Constraint {
|
/* package */class ConstraintRotLimit extends Constraint {
|
||||||
private static final int LIMIT_XROT = 0x01;
|
private static final int LIMIT_XROT = 0x01;
|
||||||
private static final int LIMIT_YROT = 0x02;
|
private static final int LIMIT_YROT = 0x02;
|
||||||
private static final int LIMIT_ZROT = 0x04;
|
private static final int LIMIT_ZROT = 0x04;
|
||||||
|
|
||||||
protected float[][] limits = new float[3][2];
|
protected float[][] limits = new float[3][2];
|
||||||
protected int flag;
|
protected int flag;
|
||||||
|
protected boolean updated;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This constructor creates the constraint instance.
|
* 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
|
* this exception is thrown when the blender file is somehow
|
||||||
* corrupted
|
* corrupted
|
||||||
*/
|
*/
|
||||||
public ConstraintRotLimit(Structure constraintStructure, Long ownerOMA,
|
public ConstraintRotLimit(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
|
||||||
Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
|
|
||||||
super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
|
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();
|
flag = ((Number) data.getFieldValue("flag")).intValue();
|
||||||
if(blenderContext.getBlenderKey().isFixUpAxis()) {
|
if (blenderContext.getBlenderKey().isFixUpAxis() && owner.spatial != null) {
|
||||||
//swapping Y and X limits flag in the bitwise flag
|
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 limitY = flag & LIMIT_YROT;
|
||||||
int limitZ = flag & LIMIT_ZROT;
|
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 |= limitY << 1;
|
||||||
flag |= limitZ >> 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
|
@Override
|
||||||
protected void bakeConstraint() {
|
protected void bakeConstraint() {
|
||||||
|
this.update();
|
||||||
Object owner = this.owner.getObject();
|
Object owner = this.owner.getObject();
|
||||||
AnimData animData = blenderContext.getAnimData(this.owner.getOma());
|
AnimData animData = blenderContext.getAnimData(this.owner.getOma());
|
||||||
if(animData != null) {
|
if (animData != null) {
|
||||||
for(Animation animation : animData.anims) {
|
for (Animation animation : animData.anims) {
|
||||||
BlenderTrack track = this.getTrack(owner, animData.skeleton, animation);
|
BlenderTrack track = this.getTrack(owner, animData.skeleton, animation);
|
||||||
Quaternion[] rotations = track.getRotations();
|
Quaternion[] rotations = track.getRotations();
|
||||||
float[] angles = new float[3];
|
float[] angles = new float[3];
|
||||||
int maxFrames = rotations.length;
|
int maxFrames = rotations.length;
|
||||||
for (int frame = 0; frame < maxFrames; ++frame) {
|
for (int frame = 0; frame < maxFrames; ++frame) {
|
||||||
rotations[frame].toAngles(angles);
|
rotations[frame].toAngles(angles);
|
||||||
System.out.print(Arrays.toString(angles) + "\t\t");
|
|
||||||
this.rotLimit(angles, ipo.calculateValue(frame));
|
this.rotLimit(angles, ipo.calculateValue(frame));
|
||||||
System.out.println(Arrays.toString(angles));
|
|
||||||
rotations[frame].fromAngles(angles);
|
rotations[frame].fromAngles(angles);
|
||||||
}
|
}
|
||||||
track.setKeyframes(track.getTimes(), track.getTranslations(), rotations, track.getScales());
|
track.setKeyframes(track.getTimes(), track.getTranslations(), rotations, track.getScales());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(owner instanceof Spatial) {
|
if (owner instanceof Spatial) {
|
||||||
Transform ownerTransform = this.owner.getTransform();
|
Transform ownerTransform = this.owner.getTransform();
|
||||||
float[] angles = ownerTransform.getRotation().toAngles(null);
|
float[] angles = ownerTransform.getRotation().toAngles(null);
|
||||||
this.rotLimit(angles, ipo.calculateValue(0));
|
this.rotLimit(angles, ipo.calculateValue(0));
|
||||||
@ -118,7 +124,7 @@ import com.jme3.scene.plugins.ogre.AnimData;
|
|||||||
}
|
}
|
||||||
angles[0] -= difference;
|
angles[0] -= difference;
|
||||||
}
|
}
|
||||||
if ((flag & LIMIT_ZROT) != 0) {
|
if ((flag & LIMIT_YROT) != 0) {
|
||||||
float difference = 0.0f;
|
float difference = 0.0f;
|
||||||
if (angles[1] < limits[1][0]) {
|
if (angles[1] < limits[1][0]) {
|
||||||
difference = (angles[1] - limits[1][0]) * influence;
|
difference = (angles[1] - limits[1][0]) * influence;
|
||||||
@ -127,7 +133,7 @@ import com.jme3.scene.plugins.ogre.AnimData;
|
|||||||
}
|
}
|
||||||
angles[1] -= difference;
|
angles[1] -= difference;
|
||||||
}
|
}
|
||||||
/*if ((flag & LIMIT_ZROT) != 0) {
|
if ((flag & LIMIT_ZROT) != 0) {
|
||||||
float difference = 0.0f;
|
float difference = 0.0f;
|
||||||
if (angles[2] < limits[2][0]) {
|
if (angles[2] < limits[2][0]) {
|
||||||
difference = (angles[2] - limits[2][0]) * influence;
|
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;
|
difference = (angles[2] - limits[2][1]) * influence;
|
||||||
}
|
}
|
||||||
angles[2] -= difference;
|
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;
|
package com.jme3.scene.plugins.blender.constraints;
|
||||||
|
|
||||||
import com.jme3.animation.Bone;
|
import com.jme3.animation.Bone;
|
||||||
import com.jme3.math.FastMath;
|
|
||||||
import com.jme3.math.Matrix4f;
|
import com.jme3.math.Matrix4f;
|
||||||
import com.jme3.math.Quaternion;
|
import com.jme3.math.Quaternion;
|
||||||
import com.jme3.math.Transform;
|
import com.jme3.math.Transform;
|
||||||
@ -9,7 +8,6 @@ import com.jme3.math.Vector3f;
|
|||||||
import com.jme3.scene.Spatial;
|
import com.jme3.scene.Spatial;
|
||||||
import com.jme3.scene.plugins.blender.BlenderContext;
|
import com.jme3.scene.plugins.blender.BlenderContext;
|
||||||
import com.jme3.scene.plugins.blender.BlenderContext.LoadedFeatureDataType;
|
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.constraints.Constraint.Space;
|
||||||
import com.jme3.scene.plugins.blender.file.DynamicArray;
|
import com.jme3.scene.plugins.blender.file.DynamicArray;
|
||||||
import com.jme3.scene.plugins.blender.file.Structure;
|
import com.jme3.scene.plugins.blender.file.Structure;
|
||||||
@ -158,20 +156,12 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Bone
|
// Bone
|
||||||
BoneContext boneContext = blenderContext.getBoneContext(oma);
|
|
||||||
switch (space) {
|
switch (space) {
|
||||||
case CONSTRAINT_SPACE_LOCAL:
|
case CONSTRAINT_SPACE_LOCAL:
|
||||||
Transform localTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation());
|
Transform localTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation());
|
||||||
localTransform.setScale(bone.getLocalScale());
|
localTransform.setScale(bone.getLocalScale());
|
||||||
return localTransform;
|
return localTransform;
|
||||||
case CONSTRAINT_SPACE_WORLD:
|
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());
|
Transform worldTransform = new Transform(bone.getWorldBindPosition(), bone.getWorldBindRotation());
|
||||||
worldTransform.setScale(bone.getWorldBindScale());
|
worldTransform.setScale(bone.getWorldBindScale());
|
||||||
return worldTransform;
|
return worldTransform;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user