1 package com.jme3.scene.plugins.blender.constraints; 2 3 import com.jme3.animation.Animation; 4 import com.jme3.math.Quaternion; 5 import com.jme3.math.Transform; 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 'Rot like' constraint type in blender. 15 * @author Marcin Roguski (Kaelthas) 16 */ 17 /*package*/ class ConstraintRotLike extends Constraint { 18 private static final int ROTLIKE_X = 0x01; 19 private static final int ROTLIKE_Y = 0x02; 20 private static final int ROTLIKE_Z = 0x04; 21 private static final int ROTLIKE_X_INVERT = 0x10; 22 private static final int ROTLIKE_Y_INVERT = 0x20; 23 private static final int ROTLIKE_Z_INVERT = 0x40; 24 private static final int ROTLIKE_OFFSET = 0x80; 25 26 protected int flag; 27 28 /** 29 * This constructor creates the constraint instance. 30 * 31 * @param constraintStructure 32 * the constraint's structure (bConstraint clss in blender 2.49). 33 * @param ownerOMA 34 * the old memory address of the constraint owner 35 * @param influenceIpo 36 * the ipo curve of the influence factor 37 * @param blenderContext 38 * the blender context 39 * @throws BlenderFileException 40 * this exception is thrown when the blender file is somehow 41 * corrupted 42 */ ConstraintRotLike(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext)43 public ConstraintRotLike(Structure constraintStructure, Long ownerOMA, 44 Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { 45 super(constraintStructure, ownerOMA, influenceIpo, blenderContext); 46 47 flag = ((Number) data.getFieldValue("flag")).intValue(); 48 } 49 50 @Override bakeConstraint()51 protected void bakeConstraint() { 52 Object owner = this.owner.getObject(); 53 AnimData animData = blenderContext.getAnimData(this.owner.getOma()); 54 if(animData != null) { 55 Transform targetTransform = this.target.getTransform(); 56 Quaternion targetRotation = targetTransform.getRotation(); 57 for(Animation animation : animData.anims) { 58 BlenderTrack track = this.getTrack(owner, animData.skeleton, animation); 59 float[] targetAngles = targetRotation.toAngles(null); 60 Quaternion[] rotations = track.getRotations(); 61 int maxFrames = rotations.length; 62 float[] angles = new float[3]; 63 for (int frame = 0; frame < maxFrames; ++frame) { 64 rotations[frame].toAngles(angles); 65 this.rotLike(rotations[frame], angles, targetAngles, ipo.calculateValue(frame)); 66 } 67 track.setKeyframes(track.getTimes(), track.getTranslations(), rotations, track.getScales()); 68 } 69 } 70 71 if(owner instanceof Spatial) { 72 Transform targetTransform = this.target.getTransform(); 73 Transform ownerTransform = this.owner.getTransform(); 74 Quaternion ownerRotation = ownerTransform.getRotation(); 75 this.rotLike(ownerRotation, ownerRotation.toAngles(null), targetTransform.getRotation().toAngles(null), ipo.calculateValue(0)); 76 this.owner.applyTransform(ownerTransform); 77 } 78 } 79 rotLike(Quaternion ownerRotation, float[] ownerAngles, float[] targetAngles, float influence)80 private void rotLike(Quaternion ownerRotation, float[] ownerAngles, float[] targetAngles, float influence) { 81 Quaternion startRotation = ownerRotation.clone(); 82 Quaternion offset = Quaternion.IDENTITY; 83 if ((flag & ROTLIKE_OFFSET) != 0) {//we add the original rotation to the copied rotation 84 offset = startRotation; 85 } 86 87 if ((flag & ROTLIKE_X) != 0) { 88 ownerAngles[0] = targetAngles[0]; 89 if ((flag & ROTLIKE_X_INVERT) != 0) { 90 ownerAngles[0] = -ownerAngles[0]; 91 } 92 } 93 if ((flag & ROTLIKE_Y) != 0) { 94 ownerAngles[1] = targetAngles[1]; 95 if ((flag & ROTLIKE_Y_INVERT) != 0) { 96 ownerAngles[1] = -ownerAngles[1]; 97 } 98 } 99 if ((flag & ROTLIKE_Z) != 0) { 100 ownerAngles[2] = targetAngles[2]; 101 if ((flag & ROTLIKE_Z_INVERT) != 0) { 102 ownerAngles[2] = -ownerAngles[2]; 103 } 104 } 105 ownerRotation.fromAngles(ownerAngles).multLocal(offset); 106 107 if(influence < 1.0f) { 108 109 // startLocation.subtractLocal(ownerLocation).normalizeLocal().mult(influence); 110 // ownerLocation.addLocal(startLocation); 111 //TODO 112 } 113 } 114 } 115