1 package com.jme3.scene.plugins.blender.constraints; 2 3 import com.jme3.animation.Animation; 4 import com.jme3.math.Transform; 5 import com.jme3.math.Vector3f; 6 import com.jme3.scene.Spatial; 7 import com.jme3.scene.plugins.blender.BlenderContext; 8 import com.jme3.scene.plugins.blender.animations.Ipo; 9 import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; 10 import com.jme3.scene.plugins.blender.file.Structure; 11 import com.jme3.scene.plugins.ogre.AnimData; 12 13 /** 14 * This class represents 'Loc like' constraint type in blender. 15 * @author Marcin Roguski (Kaelthas) 16 */ 17 /*package*/ class ConstraintLocLike extends Constraint { 18 private static final int LOCLIKE_X = 0x01; 19 private static final int LOCLIKE_Y = 0x02; 20 private static final int LOCLIKE_Z = 0x04; 21 //protected static final int LOCLIKE_TIP = 0x08;//this is deprecated in blender 22 private static final int LOCLIKE_X_INVERT = 0x10; 23 private static final int LOCLIKE_Y_INVERT = 0x20; 24 private static final int LOCLIKE_Z_INVERT = 0x40; 25 private static final int LOCLIKE_OFFSET = 0x80; 26 27 protected int flag; 28 29 /** 30 * This constructor creates the constraint instance. 31 * 32 * @param constraintStructure 33 * the constraint's structure (bConstraint clss in blender 2.49). 34 * @param ownerOMA 35 * the old memory address of the constraint owner 36 * @param influenceIpo 37 * the ipo curve of the influence factor 38 * @param blenderContext 39 * the blender context 40 * @throws BlenderFileException 41 * this exception is thrown when the blender file is somehow 42 * corrupted 43 */ ConstraintLocLike(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext)44 public ConstraintLocLike(Structure constraintStructure, Long ownerOMA, 45 Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { 46 super(constraintStructure, ownerOMA, influenceIpo, blenderContext); 47 48 flag = ((Number) data.getFieldValue("flag")).intValue(); 49 50 if(blenderContext.getBlenderKey().isFixUpAxis()) { 51 //swapping Y and X limits flag in the bitwise flag 52 int y = flag & LOCLIKE_Y; 53 int invY = flag & LOCLIKE_Y_INVERT; 54 int z = flag & LOCLIKE_Z; 55 int invZ = flag & LOCLIKE_Z_INVERT; 56 flag &= LOCLIKE_X | LOCLIKE_X_INVERT | LOCLIKE_OFFSET;//clear the other flags to swap them 57 flag |= y << 2; 58 flag |= invY << 2; 59 flag |= z >> 2; 60 flag |= invZ >> 2; 61 } 62 } 63 64 @Override bakeConstraint()65 protected void bakeConstraint() { 66 Object owner = this.owner.getObject(); 67 AnimData animData = blenderContext.getAnimData(this.owner.getOma()); 68 if(animData != null) { 69 Transform targetTransform = this.target.getTransform(); 70 for(Animation animation : animData.anims) { 71 BlenderTrack blenderTrack = this.getTrack(owner, animData.skeleton, animation); 72 Vector3f[] translations = blenderTrack.getTranslations(); 73 int maxFrames = translations.length; 74 for (int frame = 0; frame < maxFrames; ++frame) { 75 this.locLike(translations[frame], targetTransform.getTranslation(), ipo.calculateValue(frame)); 76 } 77 blenderTrack.setKeyframes(blenderTrack.getTimes(), translations, blenderTrack.getRotations(), blenderTrack.getScales()); 78 } 79 } 80 81 if(owner instanceof Spatial) { 82 Transform targetTransform = this.target.getTransform(); 83 Transform ownerTransform = this.owner.getTransform(); 84 Vector3f ownerLocation = ownerTransform.getTranslation(); 85 this.locLike(ownerLocation, targetTransform.getTranslation(), ipo.calculateValue(0)); 86 this.owner.applyTransform(ownerTransform); 87 } 88 } 89 locLike(Vector3f ownerLocation, Vector3f targetLocation, float influence)90 private void locLike(Vector3f ownerLocation, Vector3f targetLocation, float influence) { 91 Vector3f startLocation = ownerLocation.clone(); 92 Vector3f offset = Vector3f.ZERO; 93 if ((flag & LOCLIKE_OFFSET) != 0) {//we add the original location to the copied location 94 offset = startLocation; 95 } 96 97 if ((flag & LOCLIKE_X) != 0) { 98 ownerLocation.x = targetLocation.x; 99 if ((flag & LOCLIKE_X_INVERT) != 0) { 100 ownerLocation.x = -ownerLocation.x; 101 } 102 } 103 if ((flag & LOCLIKE_Y) != 0) { 104 ownerLocation.y = targetLocation.y; 105 if ((flag & LOCLIKE_Y_INVERT) != 0) { 106 ownerLocation.y = -ownerLocation.y; 107 } 108 } 109 if ((flag & LOCLIKE_Z) != 0) { 110 ownerLocation.z = targetLocation.z; 111 if ((flag & LOCLIKE_Z_INVERT) != 0) { 112 ownerLocation.z = -ownerLocation.z; 113 } 114 } 115 ownerLocation.addLocal(offset); 116 117 if(influence < 1.0f) { 118 startLocation.subtractLocal(ownerLocation).normalizeLocal().mult(influence); 119 ownerLocation.addLocal(startLocation); 120 } 121 } 122 } 123