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; } } } }