/**
  * Convert a vector (in) from world coordinate space to this spatials' local coordinate space.
  *
  * @param in vector to read from
  * @param store where to write the result
  * @return the result (store)
  */
 public Vector3f worldToLocal(final Vector3f in, final Vector3f store) {
   checkDoTransformUpdate();
   return worldTransform.transformInverseVector(in, store);
 }
  private static BoneWorldGrid makeBoneWorldGrid(
      ByteArray3d boneMeshGrid, float worldScale, MyBone bone) {
    Transform transform = BoneTransformUtils.boneTransform2(bone);
    // bounding box needed for boneMeshGrid in world grid:
    float bs = 1.0f;
    Vector3f c1 =
        transform.transformVector(new Vector3f(-bs, -bs, -bs), null).multLocal(worldScale);
    Vector3f c2 =
        transform.transformVector(new Vector3f(+bs, -bs, -bs), null).multLocal(worldScale);
    Vector3f c3 =
        transform.transformVector(new Vector3f(-bs, +bs, -bs), null).multLocal(worldScale);
    Vector3f c4 =
        transform.transformVector(new Vector3f(-bs, -bs, +bs), null).multLocal(worldScale);
    Vector3f c5 =
        transform.transformVector(new Vector3f(+bs, +bs, -bs), null).multLocal(worldScale);
    Vector3f c6 =
        transform.transformVector(new Vector3f(-bs, +bs, +bs), null).multLocal(worldScale);
    Vector3f c7 =
        transform.transformVector(new Vector3f(+bs, -bs, +bs), null).multLocal(worldScale);
    Vector3f c8 =
        transform.transformVector(new Vector3f(+bs, +bs, +bs), null).multLocal(worldScale);

    Vector3f cmin = c1.clone();
    cmin.minLocal(c2);
    cmin.minLocal(c3);
    cmin.minLocal(c4);
    cmin.minLocal(c5);
    cmin.minLocal(c6);
    cmin.minLocal(c7);
    cmin.minLocal(c8);
    Vector3f cmax = c1.clone();
    cmax.maxLocal(c2);
    cmax.maxLocal(c3);
    cmax.maxLocal(c4);
    cmax.maxLocal(c5);
    cmax.maxLocal(c6);
    cmax.maxLocal(c7);
    cmax.maxLocal(c8);

    int xsize = (int) FastMath.ceil(cmax.x - cmin.x);
    int ysize = (int) FastMath.ceil(cmax.y - cmin.y);
    int zsize = (int) FastMath.ceil(cmax.z - cmin.z);

    ByteArray3d grid = new ByteArray3d(xsize, ysize, zsize);
    int w = grid.getWidth();
    int h = grid.getHeight();
    int d = grid.getDepth();
    Vector3f v = new Vector3f();
    Vector3f inv = new Vector3f();
    Vector3f inv2 = new Vector3f();

    // we want to calculate transform: (inv - (-bs)) * (sz / (bs - (-bs)))
    // se let's precalculate it to (inv + shift) * scale
    Vector3f scale =
        new Vector3f(boneMeshGrid.getWidth(), boneMeshGrid.getHeight(), boneMeshGrid.getDepth())
            .divideLocal(bs * 2);
    Vector3f shift = Vector3f.UNIT_XYZ.mult(bs);

    for (int x = 0; x < w; x++) {
      for (int y = 0; y < h; y++) {
        // calculate inverse transform at (x,y,0) and (x,y,1), the rest of the transforms in inner
        // loop
        // can be calculated by adding (inv2-inv1) because the transforms are linear
        v.set(x, y, 0).addLocal(cmin).divideLocal(worldScale);
        transform.transformInverseVector(v, inv);
        inv.addLocal(shift).multLocal(scale);

        v.set(x, y, 1).addLocal(cmin).divideLocal(worldScale);
        transform.transformInverseVector(v, inv2);
        inv2.addLocal(shift).multLocal(scale);

        Vector3f add = inv2.subtractLocal(inv);

        for (int z = 0; z < d; z++) {
          inv.addLocal(add);
          if (inv.x >= 0
              && inv.x < boneMeshGrid.getWidth()
              && inv.y >= 0
              && inv.y < boneMeshGrid.getHeight()
              && inv.z >= 0
              && inv.z < boneMeshGrid.getDepth()) {

            grid.set(x, y, z, boneMeshGrid.get((int) inv.x, (int) inv.y, (int) inv.z));
          }
        }
      }
    }

    // Once the boneMeshGrid has been transformed into world grid, it may suffer from
    // downsampling and upsampling artifacts (because the sampling is very simple nearest-neighbor).
    // Blurring the grid helps with both issues (blur=fake antialias). It has the added benefit
    // that each BoneWorldGrid will have some "smoothing buffer" around the actual shape, so that
    // the shape blends better with other bones' shapes.
    blurGrid(grid);

    BoneWorldGrid bwg2 = new BoneWorldGrid();
    bwg2.grid = grid;
    bwg2.location = new Vector3i(Math.round(cmin.x), Math.round(cmin.y), Math.round(cmin.z));
    return bwg2;
  }