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