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