public void drawLine(
     TextureRegion tex, Vector2 p1, Vector2 p2, Color col, float width, boolean precise) {
   Vector2 v = SolMath.getVec(p2);
   v.sub(p1);
   drawLine(tex, p1.x, p1.y, SolMath.angle(v, precise), v.len(), col, width);
   SolMath.free(v);
 }
 public void drawCircle(
     TextureRegion tex, Vector2 center, float radius, Color col, float width, float vh) {
   float relRad = radius / vh;
   int pointCount = (int) (160 * relRad);
   Vector2 pos = SolMath.getVec();
   if (pointCount < 8) pointCount = 8;
   float lineLen = radius * SolMath.PI * 2 / pointCount;
   float angleStep = 360f / pointCount;
   float angleStepH = angleStep / 2;
   for (int i = 0; i < pointCount; i++) {
     float angle = angleStep * i;
     SolMath.fromAl(pos, angle, radius);
     pos.add(center);
     draw(tex, width, lineLen, (float) 0, (float) 0, pos.x, pos.y, angle + angleStepH, col);
   }
   SolMath.free(pos);
 }
  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;
    }
  }