/** * The method applies bone's current position to all of the traces of the given animations. * * @param boneContext the bone context * @param space the bone's evaluation space * @param referenceAnimData the object containing the animations */ protected void applyAnimData(BoneContext boneContext, Space space, AnimData referenceAnimData) { ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class); Transform transform = constraintHelper.getBoneTransform(space, boneContext.getBone()); AnimData animData = blenderContext.getAnimData(boneContext.getBoneOma()); for (Animation animation : referenceAnimData.anims) { BoneTrack parentTrack = (BoneTrack) animation.getTracks()[0]; float[] times = parentTrack.getTimes(); Vector3f[] translations = new Vector3f[times.length]; Quaternion[] rotations = new Quaternion[times.length]; Vector3f[] scales = new Vector3f[times.length]; Arrays.fill(translations, transform.getTranslation()); Arrays.fill(rotations, transform.getRotation()); Arrays.fill(scales, transform.getScale()); for (Animation anim : animData.anims) { anim.addTrack( new BoneTrack( animData.skeleton.getBoneIndex(boneContext.getBone()), times, translations, rotations, scales)); } } blenderContext.setAnimData(boneContext.getBoneOma(), animData); }
private static BoneTrack getFirstTrackForBone(Animation animation, int boneIndex) { BoneTrack result = null; for (Track track : animation.getTracks()) { if (track instanceof BoneTrack) { BoneTrack boneTrack = (BoneTrack) track; if (boneIndex == boneTrack.getTargetBoneIndex()) { return boneTrack; } } } return result; }
@Override public TrackWrapper clone() { if (boneTrack != null) { return new TrackWrapper(boneTrack.clone()); } return new TrackWrapper(spatialTrack.clone()); }
public void setTime( float time, float weight, AnimControl control, AnimChannel channel, TempVars vars) { if (boneTrack != null) { boneTrack.setTime(time, weight, control, channel, vars); } else { spatialTrack.setTime(time, weight, control, channel, vars); } }
/** * Set the translations, rotations and scales for this bone track * * @param times a float array with the time of each frame * @param translations the translation of the bone for each frame * @param rotations the rotation of the bone for each frame * @param scales the scale of the bone for each frame */ public void setKeyframes( float[] times, Vector3f[] translations, Quaternion[] rotations, Vector3f[] scales) { if (boneTrack != null) { boneTrack.setKeyframes(times, translations, rotations, scales); } else { spatialTrack.setKeyframes(times, translations, rotations, scales); } }
public static void setBonesSuchAs(AnimControl animControl, String animationName) { Animation animation = animControl.getAnim(animationName); int size = animControl.getSkeleton().getBoneCount(); for (int index = 0; index < size; index++) { Bone bone = animControl.getSkeleton().getBone(index); BoneTrack boneTrack = getFirstTrackForBone(animation, index); if (boneTrack != null) { Quaternion rotation = boneTrack.getRotations()[0]; Vector3f translation = boneTrack.getTranslations()[0]; Vector3f scale = boneTrack.getScales()[0]; System.out.println("Bone = " + bone.getName()); System.out.println("\tRotation = " + rotation); System.out.println("\tTranslation = " + translation); System.out.println("\tScale = " + scale); bone.setUserControl(true); bone.setUserTransforms(translation, rotation, scale); bone.updateWorldVectors(); bone.setUserControl(false); } } }
public float getLength() { return spatialTrack == null ? boneTrack.getLength() : spatialTrack.getLength(); }
/** @return the array of translations of this track */ public Vector3f[] getTranslations() { if (boneTrack != null) { return boneTrack.getTranslations(); } return spatialTrack.getTranslations(); }
/** @return the arrays of time for this track */ public float[] getTimes() { if (boneTrack != null) { return boneTrack.getTimes(); } return spatialTrack.getTimes(); }
/** @return the array of scales for this track */ public Vector3f[] getScales() { if (boneTrack != null) { return boneTrack.getScales(); } return spatialTrack.getScales(); }
/** @return the array of rotations of this track */ public Quaternion[] getRotations() { if (boneTrack != null) { return boneTrack.getRotations(); } return spatialTrack.getRotations(); }
/** * This constructor reads animation data from the object structore. The stored data is the * AnimData and additional data is armature's OMA. * * @param objectStructure the structure of the object * @param modifierStructure the structure of the modifier * @param blenderContext the blender context * @throws BlenderFileException this exception is thrown when the blender file is somehow * corrupted */ public ArmatureModifier( Structure objectStructure, Structure modifierStructure, BlenderContext blenderContext) throws BlenderFileException { if (this.validate(modifierStructure, blenderContext)) { Pointer pArmatureObject = (Pointer) modifierStructure.getFieldValue("object"); if (pArmatureObject.isNotNull()) { ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class); ArmatureHelper armatureHelper = blenderContext.getHelper(ArmatureHelper.class); Structure armatureObject = pArmatureObject.fetchData(blenderContext.getInputStream()).get(0); this.armatureObjectOMA = armatureObject.getOldMemoryAddress(); // read skeleton // changing bones matrices so that they fit the current object Structure armatureStructure = ((Pointer) armatureObject.getFieldValue("data")) .fetchData(blenderContext.getInputStream()) .get(0); Structure bonebase = (Structure) armatureStructure.getFieldValue("bonebase"); List<Structure> bonesStructures = bonebase.evaluateListBase(blenderContext); for (Structure boneStructure : bonesStructures) { BoneTransformationData rootBoneTransformationData = armatureHelper.readBoneAndItsChildren(boneStructure, null, blenderContext); armatureHelper.addBoneDataRoot(rootBoneTransformationData); } Matrix4f armatureObjectMatrix = objectHelper.getTransformationMatrix(armatureObject); Matrix4f inverseMeshObjectMatrix = objectHelper.getTransformationMatrix(objectStructure).invert(); Matrix4f additionalRootBoneTransformation = inverseMeshObjectMatrix.multLocal(armatureObjectMatrix); Bone[] bones = armatureHelper.buildBonesStructure(Long.valueOf(0L), additionalRootBoneTransformation); // read mesh indexes Structure meshStructure = ((Pointer) objectStructure.getFieldValue("data")) .fetchData(blenderContext.getInputStream()) .get(0); this.meshOMA = meshStructure.getOldMemoryAddress(); this.readVerticesWeightsData(objectStructure, meshStructure, blenderContext); // read animations ArrayList<Animation> animations = new ArrayList<Animation>(); List<FileBlockHeader> actionHeaders = blenderContext.getFileBlocks(Integer.valueOf(FileBlockHeader.BLOCK_AC00)); if (actionHeaders != null) { // it may happen that the model has armature with no actions for (FileBlockHeader header : actionHeaders) { Structure actionStructure = header.getStructure(blenderContext); String actionName = actionStructure.getName(); BoneTrack[] tracks = armatureHelper.getTracks(actionStructure, blenderContext); // determining the animation time float maximumTrackLength = 0; for (BoneTrack track : tracks) { float length = track.getLength(); if (length > maximumTrackLength) { maximumTrackLength = length; } } Animation boneAnimation = new Animation(actionName, maximumTrackLength); boneAnimation.setTracks(tracks); animations.add(boneAnimation); } } animData = new AnimData(new Skeleton(bones), animations); } } }