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 'Size like' constraint type in blender. 15 * @author Marcin Roguski (Kaelthas) 16 */ 17 /*package*/ class ConstraintSizeLike extends Constraint { 18 private static final int SIZELIKE_X = 0x01; 19 private static final int SIZELIKE_Y = 0x02; 20 private static final int SIZELIKE_Z = 0x04; 21 private static final int LOCLIKE_OFFSET = 0x80; 22 23 protected int flag; 24 25 /** 26 * This constructor creates the constraint instance. 27 * 28 * @param constraintStructure 29 * the constraint's structure (bConstraint clss in blender 2.49). 30 * @param ownerOMA 31 * the old memory address of the constraint owner 32 * @param influenceIpo 33 * the ipo curve of the influence factor 34 * @param blenderContext 35 * the blender context 36 * @throws BlenderFileException 37 * this exception is thrown when the blender file is somehow 38 * corrupted 39 */ 40 public ConstraintSizeLike(Structure constraintStructure, Long ownerOMA, 41 Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { 42 super(constraintStructure, ownerOMA, influenceIpo, blenderContext); 43 44 flag = ((Number) data.getFieldValue("flag")).intValue(); 45 if(blenderContext.getBlenderKey().isFixUpAxis()) { 46 //swapping Y and X limits flag in the bitwise flag 47 int y = flag & SIZELIKE_Y; 48 int z = flag & SIZELIKE_Z; 49 flag &= SIZELIKE_X | LOCLIKE_OFFSET;//clear the other flags to swap them 50 flag |= y << 1; 51 flag |= z >> 1; 52 } 53 } 54 55 @Override 56 protected void bakeConstraint() { 57 Object owner = this.owner.getObject(); 58 AnimData animData = blenderContext.getAnimData(this.owner.getOma()); 59 if(animData != null) { 60 Transform targetTransform = this.target.getTransform(); 61 Vector3f targetScale = targetTransform.getScale(); 62 for(Animation animation : animData.anims) { 63 BlenderTrack track = this.getTrack(owner, animData.skeleton, animation); 64 Vector3f[] scales = track.getScales(); 65 int maxFrames = scales.length; 66 for (int frame = 0; frame < maxFrames; ++frame) { 67 this.sizeLike(scales[frame], targetScale, ipo.calculateValue(frame)); 68 } 69 track.setKeyframes(track.getTimes(), track.getTranslations(), track.getRotations(), scales); 70 } 71 } 72 73 if(owner instanceof Spatial) { 74 Transform targetTransform = this.target.getTransform(); 75 Transform ownerTransform = this.owner.getTransform(); 76 this.sizeLike(ownerTransform.getScale(), targetTransform.getScale(), ipo.calculateValue(0)); 77 this.owner.applyTransform(ownerTransform); 78 } 79 } 80 81 private void sizeLike(Vector3f ownerScale, Vector3f targetScale, float influence) { 82 Vector3f offset = Vector3f.ZERO; 83 if ((flag & LOCLIKE_OFFSET) != 0) {//we add the original scale to the copied scale 84 offset = ownerScale.clone(); 85 } 86 87 if ((flag & SIZELIKE_X) != 0) { 88 ownerScale.x = targetScale.x * influence + (1.0f - influence) * ownerScale.x; 89 } 90 if ((flag & SIZELIKE_Y) != 0) { 91 ownerScale.y = targetScale.y * influence + (1.0f - influence) * ownerScale.y; 92 } 93 if ((flag & SIZELIKE_Z) != 0) { 94 ownerScale.z = targetScale.z * influence + (1.0f - influence) * ownerScale.z; 95 } 96 ownerScale.addLocal(offset); 97 } 98 } 99