• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 	 */
Constraint(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext)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 	 */
bake()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 	 */
bakeConstraint()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      */
getTrack(Object owner, Skeleton skeleton, Animation animation)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 		 */
valueOf(byte c)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 }