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 limit' constraint type in blender.
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author Marcin Roguski (Kaelthas)
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/*package*/ class ConstraintLocLimit extends Constraint {
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final int LIMIT_XMIN = 0x01;
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final int LIMIT_XMAX = 0x02;
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final int LIMIT_YMIN = 0x04;
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final int LIMIT_YMAX = 0x08;
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final int LIMIT_ZMIN = 0x10;
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final int LIMIT_ZMAX = 0x20;
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected float[][] limits = new float[3][2];
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected int flag;
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * This constructor creates the constraint instance.
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param constraintStructure
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the constraint's structure (bConstraint clss in blender 2.49).
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param ownerOMA
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the old memory address of the constraint owner
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param influenceIpo
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the ipo curve of the influence factor
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param blenderContext
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the blender context
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @throws BlenderFileException
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *             this exception is thrown when the blender file is somehow
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *             corrupted
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public ConstraintLocLimit(Structure constraintStructure, Long ownerOMA,
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		flag = ((Number) data.getFieldValue("flag")).intValue();
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if(blenderContext.getBlenderKey().isFixUpAxis()) {
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			limits[0][0] = ((Number) data.getFieldValue("xmin")).floatValue();
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			limits[0][1] = ((Number) data.getFieldValue("xmax")).floatValue();
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			limits[2][0] = -((Number) data.getFieldValue("ymin")).floatValue();
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			limits[2][1] = -((Number) data.getFieldValue("ymax")).floatValue();
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			limits[1][0] = ((Number) data.getFieldValue("zmin")).floatValue();
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			limits[1][1] = ((Number) data.getFieldValue("zmax")).floatValue();
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			//swapping Y and X limits flag in the bitwise flag
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			int ymin = flag & LIMIT_YMIN;
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			int ymax = flag & LIMIT_YMAX;
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			int zmin = flag & LIMIT_ZMIN;
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			int zmax = flag & LIMIT_ZMAX;
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			flag &= LIMIT_XMIN | LIMIT_XMAX;//clear the other flags to swap them
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			flag |= ymin << 2;
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			flag |= ymax << 2;
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			flag |= zmin >> 2;
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			flag |= zmax >> 2;
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		} else {
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			limits[0][0] = ((Number) data.getFieldValue("xmin")).floatValue();
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			limits[0][1] = ((Number) data.getFieldValue("xmax")).floatValue();
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			limits[1][0] = ((Number) data.getFieldValue("ymin")).floatValue();
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			limits[1][1] = ((Number) data.getFieldValue("ymax")).floatValue();
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			limits[2][0] = ((Number) data.getFieldValue("zmin")).floatValue();
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			limits[2][1] = ((Number) data.getFieldValue("zmax")).floatValue();
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	@Override
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	protected void bakeConstraint() {
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		Object owner = this.owner.getObject();
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		AnimData animData = blenderContext.getAnimData(this.owner.getOma());
8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if(animData != null) {
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			for(Animation animation : animData.anims) {
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				BlenderTrack track = this.getTrack(owner, animData.skeleton, animation);
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				Vector3f[] translations = track.getTranslations();
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				int maxFrames = translations.length;
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				for (int frame = 0; frame < maxFrames; ++frame) {
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					this.locLimit(translations[frame], ipo.calculateValue(frame));
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				}
8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				track.setKeyframes(track.getTimes(), translations, track.getRotations(), track.getScales());
8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if(owner instanceof Spatial) {
9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			Transform ownerTransform = this.owner.getTransform();
9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			Vector3f ownerLocation = ownerTransform.getTranslation();
9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			this.locLimit(ownerLocation, ipo.calculateValue(0));
9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			this.owner.applyTransform(ownerTransform);
9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * This method modifies the given translation.
10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param translation the translation to be modified.
10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param influence the influence value
10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	private void locLimit(Vector3f translation, float influence) {
10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if ((flag & LIMIT_XMIN) != 0) {
10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			if (translation.x < limits[0][0]) {
10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				translation.x -= (translation.x - limits[0][0]) * influence;
10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if ((flag & LIMIT_XMAX) != 0) {
11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			if (translation.x > limits[0][1]) {
11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				translation.x -= (translation.x - limits[0][1]) * influence;
11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if ((flag & LIMIT_YMIN) != 0) {
11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			if (translation.y < limits[1][0]) {
11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				translation.y -= (translation.y - limits[1][0]) * influence;
11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if ((flag & LIMIT_YMAX) != 0) {
12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			if (translation.y > limits[1][1]) {
12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				translation.y -= (translation.y - limits[1][1]) * influence;
12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if ((flag & LIMIT_ZMIN) != 0) {
12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			if (translation.z < limits[2][0]) {
12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				translation.z -= (translation.z - limits[2][0]) * influence;
12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if ((flag & LIMIT_ZMAX) != 0) {
13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			if (translation.z > limits[2][1]) {
13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				translation.z -= (translation.z - limits[2][1]) * influence;
13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
138