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