159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.scene.plugins.blender.constraints;
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.animation.Animation;
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Transform;
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Vector3f;
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Spatial;
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.BlenderContext;
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.animations.Ipo;
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.file.Structure;
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.ogre.AnimData;
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/**
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * This class represents 'Loc like' constraint type in blender.
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author Marcin Roguski (Kaelthas)
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/*package*/ class ConstraintLocLike extends Constraint {
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	private static final int LOCLIKE_X = 0x01;
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	private static final int LOCLIKE_Y = 0x02;
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	private static final int LOCLIKE_Z = 0x04;
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    //protected static final int LOCLIKE_TIP = 0x08;//this is deprecated in blender
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final int LOCLIKE_X_INVERT = 0x10;
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final int LOCLIKE_Y_INVERT = 0x20;
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final int LOCLIKE_Z_INVERT = 0x40;
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final int LOCLIKE_OFFSET = 0x80;
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected int flag;
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * This constructor creates the constraint instance.
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param constraintStructure
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the constraint's structure (bConstraint clss in blender 2.49).
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param ownerOMA
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the old memory address of the constraint owner
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param influenceIpo
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the ipo curve of the influence factor
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param blenderContext
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the blender context
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @throws BlenderFileException
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *             this exception is thrown when the blender file is somehow
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *             corrupted
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public ConstraintLocLike(Structure constraintStructure, Long ownerOMA,
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		flag = ((Number) data.getFieldValue("flag")).intValue();
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if(blenderContext.getBlenderKey().isFixUpAxis()) {
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			//swapping Y and X limits flag in the bitwise flag
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			int y = flag & LOCLIKE_Y;
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			int invY = flag & LOCLIKE_Y_INVERT;
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			int z = flag & LOCLIKE_Z;
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			int invZ = flag & LOCLIKE_Z_INVERT;
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			flag &= LOCLIKE_X | LOCLIKE_X_INVERT | LOCLIKE_OFFSET;//clear the other flags to swap them
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			flag |= y << 2;
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			flag |= invY << 2;
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			flag |= z >> 2;
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			flag |= invZ >> 2;
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	@Override
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	protected void bakeConstraint() {
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		Object owner = this.owner.getObject();
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		AnimData animData = blenderContext.getAnimData(this.owner.getOma());
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if(animData != null) {
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			Transform targetTransform = this.target.getTransform();
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			for(Animation animation : animData.anims) {
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				BlenderTrack blenderTrack = this.getTrack(owner, animData.skeleton, animation);
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				Vector3f[] translations = blenderTrack.getTranslations();
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				int maxFrames = translations.length;
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				for (int frame = 0; frame < maxFrames; ++frame) {
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					this.locLike(translations[frame], targetTransform.getTranslation(), ipo.calculateValue(frame));
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				}
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				blenderTrack.setKeyframes(blenderTrack.getTimes(), translations, blenderTrack.getRotations(), blenderTrack.getScales());
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if(owner instanceof Spatial) {
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			Transform targetTransform = this.target.getTransform();
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			Transform ownerTransform = this.owner.getTransform();
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			Vector3f ownerLocation = ownerTransform.getTranslation();
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			this.locLike(ownerLocation, targetTransform.getTranslation(), ipo.calculateValue(0));
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			this.owner.applyTransform(ownerTransform);
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	private void locLike(Vector3f ownerLocation, Vector3f targetLocation, float influence) {
9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		Vector3f startLocation = ownerLocation.clone();
9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		Vector3f offset = Vector3f.ZERO;
9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if ((flag & LOCLIKE_OFFSET) != 0) {//we add the original location to the copied location
9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			offset = startLocation;
9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if ((flag & LOCLIKE_X) != 0) {
9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			ownerLocation.x = targetLocation.x;
9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			if ((flag & LOCLIKE_X_INVERT) != 0) {
10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				ownerLocation.x = -ownerLocation.x;
10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if ((flag & LOCLIKE_Y) != 0) {
10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			ownerLocation.y = targetLocation.y;
10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			if ((flag & LOCLIKE_Y_INVERT) != 0) {
10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				ownerLocation.y = -ownerLocation.y;
10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if ((flag & LOCLIKE_Z) != 0) {
11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			ownerLocation.z = targetLocation.z;
11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			if ((flag & LOCLIKE_Z_INVERT) != 0) {
11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				ownerLocation.z = -ownerLocation.z;
11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		ownerLocation.addLocal(offset);
11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if(influence < 1.0f) {
11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			startLocation.subtractLocal(ownerLocation).normalizeLocal().mult(influence);
11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			ownerLocation.addLocal(startLocation);
12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
123