private void loadBones(Boneassignments boneAssigments, SkeletonSubMesh subMesh) {
    Array<IntArray> boneAssignments = new Array<IntArray>();
    Array<FloatArray> boneWeights = new Array<FloatArray>();

    for (int j = 0; j < subMesh.getMesh().getNumVertices(); j++) {
      boneAssignments.add(new IntArray(4));
      boneWeights.add(new FloatArray(4));
    }

    List<Vertexboneassignment> vertexboneassignment = boneAssigments.getVertexboneassignment();
    for (int j = 0; j < vertexboneassignment.size(); j++) {
      Vertexboneassignment assignment = vertexboneassignment.get(j);
      int boneIndex = assignment.boneindex;
      int vertexIndex = assignment.vertexindex;
      float weight = assignment.weight;

      boneAssignments.get(vertexIndex).add(boneIndex);
      boneWeights.get(vertexIndex).add(weight);
    }

    subMesh.boneAssignments = new int[boneAssignments.size][];
    subMesh.boneWeights = new float[boneWeights.size][];
    for (int j = 0; j < boneAssignments.size; j++) {
      subMesh.boneAssignments[j] = new int[boneAssignments.get(j).size];
      subMesh.boneWeights[j] = new float[boneWeights.get(j).size];
      for (int k = 0; k < boneAssignments.get(j).size; k++) {
        subMesh.boneAssignments[j][k] = boneAssignments.get(j).get(k);
      }
      for (int k = 0; k < boneWeights.get(j).size; k++) {
        subMesh.boneWeights[j][k] = boneWeights.get(j).get(k);
      }
    }
  }
  private SubMesh[] generateSubMeshes(Mesh ogreMesh) {
    List<Submesh> ogreSubmeshes = ogreMesh.getSubmeshes().getSubmesh();
    SubMesh[] submeshes = new SubMesh[ogreSubmeshes.size()];

    for (int i = 0; i < ogreSubmeshes.size(); i++) {
      Submesh ogreSubmesh = ogreSubmeshes.get(i);
      boolean usesTriangleList = false;

      if (ogreSubmesh.use32Bitindexes)
        throw new GdxRuntimeException("submesh '" + i + "' uses 32-bit indices");
      if (ogreSubmesh.getOperationtype().equals("triangle_list")) {
        usesTriangleList = true;
      }

      short[] indices = new short[ogreSubmesh.getFaces().count * (usesTriangleList ? 3 : 1)];
      for (int j = 0, idx = 0; j < ogreSubmesh.getFaces().count; j++) {
        Face face = ogreSubmesh.getFaces().getFace().get(j);
        indices[idx++] = face.v1;
        if (usesTriangleList || j == 0) {
          indices[idx++] = face.v2;
          indices[idx++] = face.v3;
        }
      }

      List<VertexAttribute> attributes = new ArrayList<VertexAttribute>();
      IntArray offsets = new IntArray();
      int offset = 0;

      BaseGeometry geom;

      if (ogreSubmesh.useSharedVertices) {
        geom = ogreMesh.getSharedgeometry();
      } else {
        geom = ogreSubmesh.getGeometry();
      }

      for (int j = 0; j < geom.getVertexbuffer().size(); j++) {
        Vertexbuffer buffer = geom.getVertexbuffer().get(j);
        offsets.add(offset);
        if (buffer.positions) {
          attributes.add(new VertexAttribute(Usage.Position, 3, ShaderProgram.POSITION_ATTRIBUTE));
          offset += 3;
        }
        if (buffer.normals) {
          attributes.add(new VertexAttribute(Usage.Normal, 3, ShaderProgram.NORMAL_ATTRIBUTE));
          offset += 3;
        }
        if (buffer.tangents) {
          attributes.add(
              new VertexAttribute(
                  Usage.Generic, buffer.tangentDimensions, ShaderProgram.TANGENT_ATTRIBUTE));
          offset += buffer.tangentDimensions;
        }
        if (buffer.binormals) {
          attributes.add(new VertexAttribute(Usage.Generic, 3, ShaderProgram.BINORMAL_ATTRIBUTE));
          offset += 3;
        }
        if (buffer.coloursDiffuse) {
          attributes.add(new VertexAttribute(Usage.ColorPacked, 4, ShaderProgram.COLOR_ATTRIBUTE));
          offset += 4;
        }

        for (int k = 0; k < buffer.textureCoords; k++) {
          try {
            int numTexCoords = 0;
            switch (k) {
              case 0:
                numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions0());
                break;
              case 1:
                numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions1());
                break;
              case 2:
                numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions2());
                break;
              case 3:
                numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions3());
                break;
              case 4:
                numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions4());
                break;
              case 5:
                numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions5());
                break;
              case 6:
                numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions6());
                break;
              case 7:
                numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions7());
                break;
            }
            attributes.add(
                new VertexAttribute(
                    Usage.TextureCoordinates, numTexCoords, ShaderProgram.TEXCOORD_ATTRIBUTE + k));
            offset += numTexCoords;
          } catch (NumberFormatException e) {
            throw new GdxRuntimeException(
                "Can't process texture coords with dimensions != 1, 2, 3, 4 (e.g. float1)");
          }
        }
      }
      VertexAttributes attribs = new VertexAttributes(attributes.toArray(new VertexAttribute[0]));
      int vertexSize = offset;
      float[] vertices = new float[geom.getVertexCount() * offset];
      for (int j = 0; j < geom.getVertexbuffer().size(); j++) {
        Vertexbuffer buffer = geom.getVertexbuffer().get(j);
        offset = offsets.get(j);
        int idx = offset;

        for (int k = 0; k < buffer.getVertex().size(); k++) {
          Vertex v = buffer.getVertex().get(k);
          if (v.getPosition() != null) {
            vertices[idx++] = v.getPosition().x;
            vertices[idx++] = v.getPosition().y;
            vertices[idx++] = v.getPosition().z;
          }

          if (v.getNormal() != null) {
            vertices[idx++] = v.getNormal().x;
            vertices[idx++] = v.getNormal().y;
            vertices[idx++] = v.getNormal().z;
          }

          if (v.getTangent() != null) {
            vertices[idx++] = v.getTangent().x;
            vertices[idx++] = v.getTangent().y;
            vertices[idx++] = v.getTangent().z;
            if (buffer.tangentDimensions == 4) vertices[idx++] = v.getTangent().w;
          }

          if (v.getBinormal() != null) {
            vertices[idx++] = v.getBinormal().x;
            vertices[idx++] = v.getBinormal().y;
            vertices[idx++] = v.getBinormal().z;
          }

          if (v.getColourDiffuse() != null) {
            float color = getColor(v.getColourDiffuse());
            vertices[idx++] = color;
          }

          if (v.getTexcoord() != null) {
            for (int l = 0; l < v.getTexcoord().size(); l++) {
              Texcoord texCoord = v.getTexcoord().get(l);
              int numTexCoords = 0;
              switch (l) {
                case 0:
                  numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions0());
                  break;
                case 1:
                  numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions1());
                  break;
                case 2:
                  numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions2());
                  break;
                case 3:
                  numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions3());
                  break;
                case 4:
                  numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions4());
                  break;
                case 5:
                  numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions5());
                  break;
                case 6:
                  numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions6());
                  break;
                case 7:
                  numTexCoords = Integer.valueOf(buffer.getTextureCoordDimensions7());
                  break;
              }

              if (numTexCoords == 1) {
                vertices[idx++] = texCoord.u;
              }

              if (numTexCoords == 2) {
                vertices[idx++] = texCoord.u;
                vertices[idx++] = texCoord.v;
              }

              if (numTexCoords == 3) {
                vertices[idx++] = texCoord.u;
                vertices[idx++] = texCoord.v;
                vertices[idx++] = texCoord.w;
              }

              if (numTexCoords == 4) {
                vertices[idx++] = texCoord.u;
                vertices[idx++] = texCoord.v;
                vertices[idx++] = texCoord.w;
                vertices[idx++] = texCoord.x;
              }
            }
          }

          offset += vertexSize;
          idx = offset;
        }
      }

      com.badlogic.gdx.graphics.Mesh mesh =
          new com.badlogic.gdx.graphics.Mesh(
              false, vertices.length / vertexSize, indices.length, attribs);
      mesh.setIndices(indices);
      mesh.setVertices(vertices);

      String meshName = "";
      if (ogreMesh.getSubmeshnames() != null) {
        List<Submeshname> names = ogreMesh.getSubmeshnames().getSubmeshname();
        for (int n = 0; n < names.size(); ++n) {
          if (Integer.parseInt(names.get(n).getIndex()) == i) meshName = names.get(n).getName();
        }
      }

      SubMesh subMesh;
      Boneassignments boneAssigments =
          (ogreSubmesh.getBoneassignments() != null)
              ? ogreSubmesh.getBoneassignments()
              : ogreMesh.getBoneassignments();

      if (boneAssigments != null) {
        subMesh = new SkeletonSubMesh(meshName, mesh, GL10.GL_TRIANGLES);
      } else {
        subMesh = new StillSubMesh(meshName, mesh, GL10.GL_TRIANGLES);
      }

      // FIXME ? subMesh.materialName = ogreSubmesh.material;

      if (boneAssigments != null) {
        SkeletonSubMesh subSkelMesh = (SkeletonSubMesh) subMesh;
        subSkelMesh.setVertices(vertices);
        subSkelMesh.setIndices(indices);
        subSkelMesh.skinnedVertices = new float[vertices.length];
        System.arraycopy(
            subSkelMesh.vertices, 0, subSkelMesh.skinnedVertices, 0, subSkelMesh.vertices.length);
        loadBones(boneAssigments, subSkelMesh);
      }

      if (ogreSubmesh.getOperationtype().equals("triangle_list"))
        subMesh.primitiveType = GL10.GL_TRIANGLES;
      if (ogreSubmesh.getOperationtype().equals("triangle_fan"))
        subMesh.primitiveType = GL10.GL_TRIANGLE_FAN;
      if (ogreSubmesh.getOperationtype().equals("triangle_strip"))
        subMesh.primitiveType = GL10.GL_TRIANGLE_STRIP;

      submeshes[i] = subMesh;
    }
    return submeshes;
  }