159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.scene.plugins.blender.constraints;
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.animation.Bone;
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Matrix4f;
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Quaternion;
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Transform;
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Vector3f;
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Spatial;
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.BlenderContext;
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.BlenderContext.LoadedFeatureDataType;
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.constraints.Constraint.Space;
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.file.DynamicArray;
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.file.Structure;
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/**
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * This class represents either owner or target of the constraint. It has the
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * common methods that take the evalueation space of the feature.
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author Marcin Roguski (Kaelthas)
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/* package */class Feature {
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/** The evalueation space. */
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	protected Space				space;
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/** Old memory address of the feature. */
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	protected Long				oma;
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/** The spatial that is hold by the Feature. */
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	protected Spatial			spatial;
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/** The bone that is hold by the Feature. */
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	protected Bone				bone;
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/** The blender context. */
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	protected BlenderContext	blenderContext;
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * Constructs the feature. This object should be loaded later
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * when it is read from the blender file.
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * The update method should be called before the feature is used.
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param space
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the spatial's evaluation space
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param oma
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the spatial's old memory address
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param blenderContext
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the blender context
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public Feature(Space space, Long oma, BlenderContext blenderContext) {
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		this.space = space;
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		this.oma = oma;
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		this.blenderContext = blenderContext;
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * Constructs the feature based on spatial.
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param spatial
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the spatial
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param space
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the spatial's evaluation space
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param oma
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the spatial's old memory address
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param blenderContext
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the blender context
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public Feature(Spatial spatial, Space space, Long oma, BlenderContext blenderContext) {
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		this(space, oma, blenderContext);
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		this.blenderContext = blenderContext;
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * Constructs the feature based on bone.
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param bone
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the bone
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param space
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the bone evaluation space
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param oma
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the bone old memory address
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param blenderContext
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the blender context
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public Feature(Bone bone, Space space, Long oma, BlenderContext blenderContext) {
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		this(space, oma, blenderContext);
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		this.bone = bone;
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * This method should be called before the feature is used.
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * It may happen that the object this feature refers to was not yet loaded from blend file
8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * when the instance of this class was created.
8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public void update() {
9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		Object owner = blenderContext.getLoadedFeature(oma, LoadedFeatureDataType.LOADED_FEATURE);
9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if(owner instanceof Spatial) {
9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			this.spatial = (Spatial) owner;
9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		} else if(owner instanceof Bone) {
9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			this.bone = (Bone) owner;
9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		} else {
9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			throw new IllegalStateException("Unknown type of owner: " + owner.getClass());
9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @return the feature's old memory address
10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public Long getOma() {
10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		return oma;
10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @return the object held by the feature (either bone or spatial)
11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public Object getObject() {
11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if (spatial != null) {
11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			return spatial;
11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		return bone;
11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @return the feature's transform depending on the evaluation space
12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	@SuppressWarnings("unchecked")
12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public Transform getTransform() {
12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if (spatial != null) {
12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			switch (space) {
12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				case CONSTRAINT_SPACE_LOCAL:
12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					Structure targetStructure = (Structure) blenderContext.getLoadedFeature(oma, LoadedFeatureDataType.LOADED_STRUCTURE);
12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					DynamicArray<Number> locArray = ((DynamicArray<Number>) targetStructure.getFieldValue("loc"));
12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					Vector3f loc = new Vector3f(locArray.get(0).floatValue(), locArray.get(1).floatValue(), locArray.get(2).floatValue());
13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					DynamicArray<Number> rotArray = ((DynamicArray<Number>) targetStructure.getFieldValue("rot"));
13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					Quaternion rot = new Quaternion(new float[] { rotArray.get(0).floatValue(), rotArray.get(1).floatValue(), rotArray.get(2).floatValue() });
13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					DynamicArray<Number> sizeArray = ((DynamicArray<Number>) targetStructure.getFieldValue("size"));
13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					Vector3f size = new Vector3f(sizeArray.get(0).floatValue(), sizeArray.get(1).floatValue(), sizeArray.get(2).floatValue());
13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					if (blenderContext.getBlenderKey().isFixUpAxis()) {
13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						float y = loc.y;
13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						loc.y = loc.z;
13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						loc.z = -y;
13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						y = rot.getY();
14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						float z = rot.getZ();
14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						rot.set(rot.getX(), z, -y, rot.getW());
14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						y = size.y;
14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						size.y = size.z;
14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						size.z = y;
14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					}
14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					Transform result = new Transform(loc, rot);
15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					result.setScale(size);
15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					return result;
15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				case CONSTRAINT_SPACE_WORLD:
15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					return spatial.getWorldTransform();
15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				default:
15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					throw new IllegalStateException("Invalid space type for target object: " + space.toString());
15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		// Bone
15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		switch (space) {
16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case CONSTRAINT_SPACE_LOCAL:
16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				Transform localTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation());
16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				localTransform.setScale(bone.getLocalScale());
16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				return localTransform;
16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case CONSTRAINT_SPACE_WORLD:
16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				Transform worldTransform = new Transform(bone.getWorldBindPosition(), bone.getWorldBindRotation());
16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				worldTransform.setScale(bone.getWorldBindScale());
16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				return worldTransform;
16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case CONSTRAINT_SPACE_POSE:
16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				Transform poseTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation());
17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				poseTransform.setScale(bone.getLocalScale());
17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				return poseTransform;
17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			case CONSTRAINT_SPACE_PARLOCAL:
17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				Transform parentLocalTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation());
17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				parentLocalTransform.setScale(bone.getLocalScale());
17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				return parentLocalTransform;
17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			default:
17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				throw new IllegalStateException("Invalid space type for target object: " + space.toString());
17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * This method applies the given transform to the feature in the proper
18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * evaluation space.
18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *
18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param transform
18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the transform to be applied
18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public void applyTransform(Transform transform) {
18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if (spatial != null) {
19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			switch (space) {
19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				case CONSTRAINT_SPACE_LOCAL:
19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					Transform ownerLocalTransform = spatial.getLocalTransform();
19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					ownerLocalTransform.getTranslation().addLocal(transform.getTranslation());
19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					ownerLocalTransform.getRotation().multLocal(transform.getRotation());
19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					ownerLocalTransform.getScale().multLocal(transform.getScale());
19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					break;
19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				case CONSTRAINT_SPACE_WORLD:
19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					Matrix4f m = this.getParentWorldTransformMatrix();
19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					m.invertLocal();
20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					Matrix4f matrix = this.toMatrix(transform);
20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					m.multLocal(matrix);
20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					float scaleX = (float) Math.sqrt(m.m00 * m.m00 + m.m10 * m.m10 + m.m20 * m.m20);
20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					float scaleY = (float) Math.sqrt(m.m01 * m.m01 + m.m11 * m.m11 + m.m21 * m.m21);
20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					float scaleZ = (float) Math.sqrt(m.m02 * m.m02 + m.m12 * m.m12 + m.m22 * m.m22);
20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					transform.setTranslation(m.toTranslationVector());
20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					transform.setRotation(m.toRotationQuat());
20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					transform.setScale(scaleX, scaleY, scaleZ);
21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					spatial.setLocalTransform(transform);
21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					break;
21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				case CONSTRAINT_SPACE_PARLOCAL:
21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				case CONSTRAINT_SPACE_POSE:
21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					throw new IllegalStateException("Invalid space type (" + space.toString() + ") for owner object.");
21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				default:
21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					throw new IllegalStateException("Invalid space type for target object: " + space.toString());
21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		} else {// Bone
21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			switch (space) {
22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				case CONSTRAINT_SPACE_LOCAL:
22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					bone.setBindTransforms(transform.getTranslation(), transform.getRotation(), transform.getScale());
22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					break;
22359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				case CONSTRAINT_SPACE_WORLD:
22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					Matrix4f m = this.getParentWorldTransformMatrix();
22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//					m.invertLocal();
22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					transform.setTranslation(m.mult(transform.getTranslation()));
22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					transform.setRotation(m.mult(transform.getRotation(), null));
22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					transform.setScale(transform.getScale());
22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					bone.setBindTransforms(transform.getTranslation(), transform.getRotation(), transform.getScale());
23059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//					float x = FastMath.HALF_PI/2;
23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//					float y = -FastMath.HALF_PI;
23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//					float z = -FastMath.HALF_PI/2;
23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta//					bone.setBindTransforms(new Vector3f(0,0,0), new Quaternion().fromAngles(x, y, z), new Vector3f(1,1,1));
23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					break;
23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				case CONSTRAINT_SPACE_PARLOCAL:
23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					Vector3f parentLocalTranslation = bone.getLocalPosition().add(transform.getTranslation());
23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					Quaternion parentLocalRotation = bone.getLocalRotation().mult(transform.getRotation());
23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					bone.setBindTransforms(parentLocalTranslation, parentLocalRotation, transform.getScale());
23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					break;
24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				case CONSTRAINT_SPACE_POSE:
24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					bone.setBindTransforms(transform.getTranslation(), transform.getRotation(), transform.getScale());
24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					break;
24359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				default:
24459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					throw new IllegalStateException("Invalid space type for target object: " + space.toString());
24559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
24659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
24759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
24859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
24959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
25059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @return world transform matrix of the feature
25159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
25259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public Matrix4f getWorldTransformMatrix() {
25359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if (spatial != null) {
25459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			Matrix4f result = new Matrix4f();
25559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			Transform t = spatial.getWorldTransform();
25659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			result.setTransform(t.getTranslation(), t.getScale(), t.getRotation().toRotationMatrix());
25759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			return result;
25859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
25959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		// Bone
26059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		Matrix4f result = new Matrix4f();
26159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		result.setTransform(bone.getWorldBindPosition(), bone.getWorldBindScale(), bone.getWorldBindRotation().toRotationMatrix());
26259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		return result;
26359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
26459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
26559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
26659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @return world transform matrix of the feature's parent or identity matrix
26759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *         if the feature has no parent
26859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
26959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public Matrix4f getParentWorldTransformMatrix() {
27059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		Matrix4f result = new Matrix4f();
27159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if (spatial != null) {
27259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			if (spatial.getParent() != null) {
27359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				Transform t = spatial.getParent().getWorldTransform();
27459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				result.setTransform(t.getTranslation(), t.getScale(), t.getRotation().toRotationMatrix());
27559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
27659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		} else {// Bone
27759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			Bone parent = bone.getParent();
27859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			if (parent != null) {
27959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				result.setTransform(parent.getWorldBindPosition(), parent.getWorldBindScale(), parent.getWorldBindRotation().toRotationMatrix());
28059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
28159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
28259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		return result;
28359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
28459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
28559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
28659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * Converts given transform to the matrix.
28759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *
28859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param transform
28959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the transform to be converted
29059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @return 4x4 matri that represents the given transform
29159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
29259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	protected Matrix4f toMatrix(Transform transform) {
29359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		Matrix4f result = Matrix4f.IDENTITY;
29459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if (transform != null) {
29559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			result = new Matrix4f();
29659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			result.setTranslation(transform.getTranslation());
29759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			result.setRotationQuaternion(transform.getRotation());
29859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			result.setScale(transform.getScale());
29959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
30059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		return result;
30159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
30259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
303