blob: 74e2ec1f8c483dafb9702511bb5926d1242a1908 [file] [log] [blame]
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;
}
}
}
}