Home | History | Annotate | Download | only in constraints
      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