public static KeyframeSet ofFloat(float... values) { int numKeyframes = values.length; FloatKeyframe keyframes[] = new FloatKeyframe[Math.max(numKeyframes, 2)]; if (numKeyframes == 1) { keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f); keyframes[1] = (FloatKeyframe) Keyframe.ofFloat(1f, values[0]); } else { keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f, values[0]); for (int i = 1; i < numKeyframes; ++i) { keyframes[i] = (FloatKeyframe) Keyframe.ofFloat((float) i / (numKeyframes - 1), values[i]); } } return new FloatKeyframeSet(keyframes); }
public KeyframeSet(Keyframe... keyframes) { mNumKeyframes = keyframes.length; mKeyframes = new ArrayList<Keyframe>(); mKeyframes.addAll(Arrays.asList(keyframes)); mFirstKeyframe = mKeyframes.get(0); mLastKeyframe = mKeyframes.get(mNumKeyframes - 1); mInterpolator = mLastKeyframe.getInterpolator(); }
/** * Internal function (called from ObjectAnimator) to set up the setter and getter prior to running * the animation. If the setter has not been manually set for this object, it will be derived * automatically given the property name, target object, and types of values supplied. If no * getter has been set, it will be supplied iff any of the supplied values was null. If there is a * null value, then the getter (supplied or derived) will be called to set those null values to * the current value of the property on the target object. * * @param target The object on which the setter (and possibly getter) exist. */ void setupSetterAndGetter(Object target) { // if (mProperty != null) { // // check to make sure that mProperty is on the class of target // try { // Object testValue = mProperty.get(target); // for (Keyframe kf : mKeyframeSet.mKeyframes) { // if (!kf.hasValue()) { // kf.setValue(mProperty.get(target)); // } // } // return; // } catch (ClassCastException e) { // Log.e("PropertyValuesHolder","No such property (" + mProperty.getName() + // ") on target object " + target + ". Trying reflection instead"); // mProperty = null; // } // } Class targetClass = target.getClass(); if (mSetter == null) { setupSetter(targetClass); } for (Keyframe kf : mKeyframeSet.mKeyframes) { if (!kf.hasValue()) { if (mGetter == null) { setupGetter(targetClass); } try { kf.setValue(mGetter.invoke(target)); } catch (InvocationTargetException e) { Log.e("PropertyValuesHolder", e.toString()); } catch (IllegalAccessException e) { Log.e("PropertyValuesHolder", e.toString()); } } } }
/** * Utility function to set the value stored in a particular Keyframe. The value used is whatever * the value is for the property name specified in the keyframe on the target object. * * @param target The target object from which the current value should be extracted. * @param kf The keyframe which holds the property name and value. */ private void setupValue(Object target, Keyframe kf) { // if (mProperty != null) { // kf.setValue(mProperty.get(target)); // } try { if (mGetter == null) { Class targetClass = target.getClass(); setupGetter(targetClass); } kf.setValue(mGetter.invoke(target)); } catch (InvocationTargetException e) { Log.e("PropertyValuesHolder", e.toString()); } catch (IllegalAccessException e) { Log.e("PropertyValuesHolder", e.toString()); } }
/** * Gets the animated value, given the elapsed fraction of the animation (interpolated by the * animation's interpolator) and the evaluator used to calculate in-between values. This function * maps the input fraction to the appropriate keyframe interval and a fraction between them and * returns the interpolated value. Note that the input fraction may fall outside the [0-1] bounds, * if the animation's interpolator made that happen (e.g., a spring interpolation that might send * the fraction past 1.0). We handle this situation by just using the two keyframes at the * appropriate end when the value is outside those bounds. * * @param fraction The elapsed fraction of the animation * @return The animated value. */ public Object getValue(float fraction) { // Special-case optimization for the common case of only two keyframes if (mNumKeyframes == 2) { if (mInterpolator != null) { fraction = mInterpolator.getInterpolation(fraction); } return mEvaluator.evaluate(fraction, mFirstKeyframe.getValue(), mLastKeyframe.getValue()); } if (fraction <= 0f) { final Keyframe nextKeyframe = mKeyframes.get(1); final TimeInterpolator interpolator = nextKeyframe.getInterpolator(); if (interpolator != null) { fraction = interpolator.getInterpolation(fraction); } final float prevFraction = mFirstKeyframe.getFraction(); float intervalFraction = (fraction - prevFraction) / (nextKeyframe.getFraction() - prevFraction); return mEvaluator.evaluate( intervalFraction, mFirstKeyframe.getValue(), nextKeyframe.getValue()); } else if (fraction >= 1f) { final Keyframe prevKeyframe = mKeyframes.get(mNumKeyframes - 2); final TimeInterpolator interpolator = mLastKeyframe.getInterpolator(); if (interpolator != null) { fraction = interpolator.getInterpolation(fraction); } final float prevFraction = prevKeyframe.getFraction(); float intervalFraction = (fraction - prevFraction) / (mLastKeyframe.getFraction() - prevFraction); return mEvaluator.evaluate( intervalFraction, prevKeyframe.getValue(), mLastKeyframe.getValue()); } Keyframe prevKeyframe = mFirstKeyframe; for (int i = 1; i < mNumKeyframes; ++i) { Keyframe nextKeyframe = mKeyframes.get(i); if (fraction < nextKeyframe.getFraction()) { final TimeInterpolator interpolator = nextKeyframe.getInterpolator(); if (interpolator != null) { fraction = interpolator.getInterpolation(fraction); } final float prevFraction = prevKeyframe.getFraction(); float intervalFraction = (fraction - prevFraction) / (nextKeyframe.getFraction() - prevFraction); return mEvaluator.evaluate( intervalFraction, prevKeyframe.getValue(), nextKeyframe.getValue()); } prevKeyframe = nextKeyframe; } // shouldn't reach here return mLastKeyframe.getValue(); }
public Animation read(FileHandle handle) { XmlReader rdr = new XmlReader(); try { Element root = rdr.parse(handle); int frameRate = Integer.parseInt(root.getChildByName("FrameRate").getText()); int loopFrame = Integer.parseInt(root.getChildByName("LoopFrame").getText()); Animation anim = new Animation(); anim.FrameRate = frameRate; anim.LoopFrame = loopFrame; anim.Textures = new ArrayList<TextureEntry>(); anim.Loop = loopFrame != -1; anim.Keyframes = new ArrayList<Keyframe>(); for (int i = 0; i < root.getChildCount(); ++i) { Element ch = root.getChild(i); if (ch.getName().equals("Texture")) { TextureRegion reg = imgSrc.getImage(ch.getText()); if (reg != null) { TextureAtlas.AtlasRegion r = (TextureAtlas.AtlasRegion) reg; anim.Textures.add( new TextureEntry( reg, new TextureBounds( new Rectangle(0, 0, r.originalWidth, r.originalHeight), new Vector2(r.originalWidth / 2, r.originalHeight / 2)))); } else { throw new Exception("Unable to resolve image: " + ch.getText()); } } } for (int i = 0; i < root.getChildCount(); ++i) { Element ch = root.getChild(i); if (ch.getName().equals("Keyframe")) { Keyframe frame = new Keyframe(); frame.Bones = new ArrayList<Bone>(); frame.FrameNumber = ch.getIntAttribute("frame"); frame.Trigger = ch.getAttribute("trigger", ""); frame.FlipHorizontally = ch.getAttribute("hflip", "False").equals("True"); frame.FlipVertically = ch.getAttribute("vflip", "False").equals("True"); for (int j = 0; j < ch.getChildCount(); ++j) { Element bone = ch.getChild(j); if (bone.getName().equals("Bone")) { Element posElem = bone.getChildByName("Position"); Element sclElem = bone.getChildByName("Scale"); Vector2 pos = new Vector2(); Vector2 scl = new Vector2(); pos.x = Float.parseFloat(posElem.getChildByName("X").getText()); pos.y = Float.parseFloat(posElem.getChildByName("Y").getText()); scl.x = Float.parseFloat(sclElem.getChildByName("X").getText()); scl.y = Float.parseFloat(sclElem.getChildByName("Y").getText()); Bone b = new Bone(); b.Hidden = bone.getChildByName("Hidden").getText().equals("True"); b.Name = bone.getAttribute("name"); b.TextureFlipHorizontal = bone.getChildByName("TextureFlipHorizontal").getText().equals("True"); b.TextureFlipVertical = bone.getChildByName("TextureFlipVertical").getText().equals("True"); b.ParentIndex = Integer.parseInt(bone.getChildByName("ParentIndex").getText()); b.TextureIndex = Integer.parseInt(bone.getChildByName("TextureIndex").getText()); b.Rotation = Float.parseFloat(bone.getChildByName("Rotation").getText()); b.Position = pos; b.Scale = scl; b.SelfIndex = j; frame.Bones.add(b); } } frame.SortBones(); anim.Keyframes.add(frame); } float fr = 1.0f / anim.FrameRate; anim.LoopTime = anim.LoopFrame * anim.FrameRate; anim.Loop = anim.LoopFrame != -1; for (Keyframe kf : anim.Keyframes) { kf.FrameTime = fr * kf.FrameNumber; } } return anim; } catch (Exception ex) { Gdx.app.log("AnimationReader", "read", ex); return null; } }