blob: 834dfb43a005820d7142d91386be5675c4c6ef05 [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 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);
}
}
}