• 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.Skeleton;
5 import com.jme3.scene.plugins.blender.BlenderContext;
6 import com.jme3.scene.plugins.blender.animations.CalculationBone;
7 import com.jme3.scene.plugins.blender.animations.Ipo;
8 import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
9 import com.jme3.scene.plugins.blender.file.Structure;
10 import java.util.logging.Logger;
11 
12 /**
13  * This class represents 'Inverse kinematics' constraint type in blender.
14  * @author Marcin Roguski (Kaelthas)
15  */
16 /*package*/ class ConstraintInverseKinematics extends Constraint {
17 	private static final Logger LOGGER = Logger.getLogger(ConstraintInverseKinematics.class.getName());
18 	private static final float IK_SOLVER_ERROR = 0.5f;
19 
20 	/**
21 	 * This constructor creates the constraint instance.
22 	 *
23 	 * @param constraintStructure
24 	 *            the constraint's structure (bConstraint clss in blender 2.49).
25 	 * @param ownerOMA
26 	 *            the old memory address of the constraint owner
27 	 * @param influenceIpo
28 	 *            the ipo curve of the influence factor
29 	 * @param blenderContext
30 	 *            the blender context
31 	 * @throws BlenderFileException
32 	 *             this exception is thrown when the blender file is somehow
33 	 *             corrupted
34 	 */
ConstraintInverseKinematics(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext)35 	public ConstraintInverseKinematics(Structure constraintStructure,
36 			Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
37 		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
38 	}
39 
40 	@Override
bakeConstraint()41 	protected void bakeConstraint() {
42 //		try {
43 			// IK solver is only attached to bones
44 //			Bone ownerBone = (Bone) blenderContext.getLoadedFeature(ownerOMA, LoadedFeatureDataType.LOADED_FEATURE);
45 //			AnimData animData = blenderContext.getAnimData(ownerOMA);
46 //			if(animData == null) {
47 				//TODO: to nie moxe byx null, utworzyx dane bez ruchu, w zalexnoxci czy target six rusza
48 //			}
49 
50 			//prepare a list of all parents of this bone
51 //			CalculationBone[] bones = this.getBonesToCalculate(skeleton, boneAnimation);
52 
53 			// get the target point
54 //			Object targetObject = this.getTarget(LoadedFeatureDataType.LOADED_FEATURE);
55 //			Vector3f pt = null;// Point Target
56 //			if (targetObject instanceof Bone) {
57 //				pt = ((Bone) targetObject).getModelSpacePosition();
58 //			} else if (targetObject instanceof Spatial) {
59 //				pt = ((Spatial) targetObject).getWorldTranslation();
60 //			} else if (targetObject instanceof Skeleton) {
61 //				Structure armatureNodeStructure = (Structure) this.getTarget(LoadedFeatureDataType.LOADED_STRUCTURE);
62 //				ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
63 //				Transform transform = objectHelper.getTransformation(armatureNodeStructure, blenderContext);
64 //				pt = transform.getTranslation();
65 //			} else {
66 //				throw new IllegalStateException(
67 //						"Unknown target object type! Should be Node, Bone or Skeleton and there is: "
68 //						+ targetObject.getClass().getName());
69 //			}
70 
71 			//fetching the owner's bone track
72 //			BoneTrack ownerBoneTrack = null;
73 //			int boneIndex = skeleton.getBoneIndex(ownerBone);
74 //			for (int i = 0; i < boneAnimation.getTracks().length; ++i) {
75 //				if (boneAnimation.getTracks()[i].getTargetBoneIndex() == boneIndex) {
76 //					ownerBoneTrack = boneAnimation.getTracks()[i];
77 //					break;
78 //				}
79 //			}
80 //			int ownerBoneFramesCount = ownerBoneTrack==null ? 0 : ownerBoneTrack.getTimes().length;
81 //
82 //			// preparing data
83 //			int maxIterations = ((Number) data.getFieldValue("iterations")).intValue();
84 //			CalculationBone[] bones = this.getBonesToCalculate(ownerBone, skeleton, boneAnimation);
85 //			for (int i = 0; i < bones.length; ++i) {
86 //				System.out.println(Arrays.toString(bones[i].track.getTranslations()));
87 //				System.out.println(Arrays.toString(bones[i].track.getRotations()));
88 //				System.out.println("===============================");
89 //			}
90 //			Quaternion rotation = new Quaternion();
91 //			//all tracks should have the same amount of frames
92 //			int framesCount = bones[0].getBoneFramesCount();
93 //			assert framesCount >=1;
94 //			for (int frame = 0; frame < framesCount; ++frame) {
95 //				float error = IK_SOLVER_ERROR;
96 //				int iteration = 0;
97 //				while (error >= IK_SOLVER_ERROR && iteration <= maxIterations) {
98 //					// rotating the bones
99 //					for (int i = 0; i < bones.length - 1; ++i) {
100 //						Vector3f pe = bones[i].getEndPoint();
101 //						Vector3f pc = bones[i + 1].getWorldTranslation().clone();
102 //
103 //						Vector3f peSUBpc = pe.subtract(pc).normalizeLocal();
104 //						Vector3f ptSUBpc = pt.subtract(pc).normalizeLocal();
105 //
106 //						float theta = FastMath.acos(peSUBpc.dot(ptSUBpc));
107 //						Vector3f direction = peSUBpc.cross(ptSUBpc).normalizeLocal();
108 //						bones[i].rotate(rotation.fromAngleAxis(theta, direction), frame);
109 //					}
110 //					error = pt.subtract(bones[0].getEndPoint()).length();
111 //					++iteration;
112 //				}
113 //			}
114 //
115 //			for (CalculationBone bone : bones) {
116 //				bone.applyCalculatedTracks();
117 //			}
118 //
119 //			System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
120 //			for (int i = 0; i < bones.length; ++i) {
121 //				System.out.println(Arrays.toString(bones[i].track.getTranslations()));
122 //				System.out.println(Arrays.toString(bones[i].track.getRotations()));
123 //				System.out.println("===============================");
124 //			}
125 //		} catch(BlenderFileException e) {
126 //			LOGGER.severe(e.getLocalizedMessage());
127 //		}
128 	}
129 
130 	/**
131 	 * This method returns bones used for rotation calculations.
132 	 * @param bone
133 	 *        the bone to which the constraint is applied
134 	 * @param skeleton
135 	 *        the skeleton owning the bone and its ancestors
136 	 * @param boneAnimation
137 	 *        the bone animation data that stores the traces for the skeleton's bones
138 	 * @return a list of bones to imitate the bone's movement during IK solving
139 	 */
getBonesToCalculate(Skeleton skeleton, Animation boneAnimation)140 	private CalculationBone[] getBonesToCalculate(Skeleton skeleton, Animation boneAnimation) {
141 //		Bone ownerBone = (Bone) blenderContext.getLoadedFeature(ownerOMA, LoadedFeatureDataType.LOADED_FEATURE);
142 //		List<CalculationBone> bonesList = new ArrayList<CalculationBone>();
143 //		do {
144 //			bonesList.add(new CalculationBone(ownerBone, 1));
145 //			int boneIndex = skeleton.getBoneIndex(ownerBone);
146 //			for (int i = 0; i < boneAnimation.getTracks().length; ++i) {
147 //				if (((BoneTrack[])boneAnimation.getTracks())[i].getTargetBoneIndex() == boneIndex) {
148 //					bonesList.add(new CalculationBone(ownerBone, (BoneTrack)boneAnimation.getTracks()[i]));
149 //					break;
150 //				}
151 //			}
152 //			ownerBone = ownerBone.getParent();
153 //		} while (ownerBone != null);
154 //		//attaching children
155 //		CalculationBone[] result = bonesList.toArray(new CalculationBone[bonesList.size()]);
156 //		for (int i = result.length - 1; i > 0; --i) {
157 //			result[i].attachChild(result[i - 1]);
158 //		}
159 //		return result;
160 		return null;
161 	}
162 }
163