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.animation.Bone;
      5 import com.jme3.animation.BoneTrack;
      6 import com.jme3.animation.Skeleton;
      7 import com.jme3.animation.SpatialTrack;
      8 import com.jme3.animation.Track;
      9 import com.jme3.scene.Spatial;
     10 import com.jme3.scene.plugins.blender.BlenderContext;
     11 import com.jme3.scene.plugins.blender.animations.Ipo;
     12 import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
     13 import com.jme3.scene.plugins.blender.file.Pointer;
     14 import com.jme3.scene.plugins.blender.file.Structure;
     15 import com.jme3.scene.plugins.blender.objects.ObjectHelper;
     16 
     17 /**
     18  * The implementation of a constraint.
     19  *
     20  * @author Marcin Roguski (Kaelthas)
     21  */
     22 public abstract class Constraint {
     23 	/** The name of this constraint. */
     24 	protected final String name;
     25 	/** The constraint's owner. */
     26 	protected final Feature owner;
     27 	/** The constraint's target. */
     28 	protected final Feature target;
     29 	/** The structure with constraint's data. */
     30 	protected final Structure data;
     31 	/** The ipo object defining influence. */
     32 	protected final Ipo ipo;
     33 	/** The blender context. */
     34 	protected final BlenderContext blenderContext;
     35 
     36 	/**
     37 	 * This constructor creates the constraint instance.
     38 	 *
     39 	 * @param constraintStructure
     40 	 *            the constraint's structure (bConstraint clss in blender 2.49).
     41 	 * @param ownerOMA
     42 	 *            the old memory address of the constraint owner
     43 	 * @param influenceIpo
     44 	 *            the ipo curve of the influence factor
     45 	 * @param blenderContext
     46 	 *            the blender context
     47 	 * @throws BlenderFileException
     48 	 *             this exception is thrown when the blender file is somehow
     49 	 *             corrupted
     50 	 */
     51 	public Constraint(Structure constraintStructure, Long ownerOMA,
     52 			Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
     53 		this.blenderContext = blenderContext;
     54 		this.name = constraintStructure.getFieldValue("name").toString();
     55 		Pointer pData = (Pointer) constraintStructure.getFieldValue("data");
     56 		if (pData.isNotNull()) {
     57 			data = pData.fetchData(blenderContext.getInputStream()).get(0);
     58 			Pointer pTar = (Pointer)data.getFieldValue("tar");
     59 			if(pTar!= null && pTar.isNotNull()) {
     60 				Structure targetStructure = pTar.fetchData(blenderContext.getInputStream()).get(0);
     61 				Long targetOMA = pTar.getOldMemoryAddress();
     62 				Space targetSpace = Space.valueOf(((Number) constraintStructure.getFieldValue("tarspace")).byteValue());
     63 				ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
     64 				Spatial target = (Spatial) objectHelper.toObject(targetStructure, blenderContext);
     65 				this.target = new Feature(target, targetSpace, targetOMA, blenderContext);
     66 			} else {
     67 				this.target = null;
     68 			}
     69 		} else {
     70 			throw new BlenderFileException("The constraint has no data specified!");
     71 		}
     72 		Space ownerSpace = Space.valueOf(((Number) constraintStructure.getFieldValue("ownspace")).byteValue());
     73 		this.owner = new Feature(ownerSpace, ownerOMA, blenderContext);
     74 		this.ipo = influenceIpo;
     75 	}
     76 
     77 	/**
     78 	 * This method bakes the required sontraints into its owner.
     79 	 */
     80 	public void bake() {
     81 		this.owner.update();
     82 		if(this.target != null) {
     83 			this.target.update();
     84 		}
     85 		this.bakeConstraint();
     86 	}
     87 
     88 	/**
     89 	 * Bake the animation's constraints into its owner.
     90 	 */
     91 	protected abstract void bakeConstraint();
     92 
     93     /**
     94      * This method returns the bone traces for the bone that is affected by the given constraint.
     95      * @param skeleton
     96      *        the skeleton containing bones
     97      * @param boneAnimation
     98      *        the bone animation that affects the skeleton
     99      * @return the bone track for the bone that is being affected by the constraint
    100      */
    101     protected BlenderTrack getTrack(Object owner, Skeleton skeleton, Animation animation) {
    102     	if(owner instanceof Bone) {
    103     		int boneIndex = skeleton.getBoneIndex((Bone) owner);
    104     		for (Track track : animation.getTracks()) {
    105                 if (((BoneTrack) track).getTargetBoneIndex() == boneIndex) {
    106                     return new BlenderTrack(((BoneTrack) track));
    107                 }
    108             }
    109     		throw new IllegalStateException("Cannot find track for: " + owner);
    110     	} else {
    111     		return new BlenderTrack((SpatialTrack)animation.getTracks()[0]);
    112     	}
    113     }
    114 
    115 	/**
    116 	 * The space of target or owner transformation.
    117 	 *
    118 	 * @author Marcin Roguski (Kaelthas)
    119 	 */
    120 	public static enum Space {
    121 
    122 		CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_PARLOCAL, CONSTRAINT_SPACE_INVALID;
    123 
    124 		/**
    125 		 * This method returns the enum instance when given the appropriate
    126 		 * value from the blend file.
    127 		 *
    128 		 * @param c
    129 		 *            the blender's value of the space modifier
    130 		 * @return the scape enum instance
    131 		 */
    132 		public static Space valueOf(byte c) {
    133 			switch (c) {
    134 				case 0:
    135 					return CONSTRAINT_SPACE_WORLD;
    136 				case 1:
    137 					return CONSTRAINT_SPACE_LOCAL;
    138 				case 2:
    139 					return CONSTRAINT_SPACE_POSE;
    140 				case 3:
    141 					return CONSTRAINT_SPACE_PARLOCAL;
    142 				default:
    143 					return CONSTRAINT_SPACE_INVALID;
    144 			}
    145 		}
    146 	}
    147 }