Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get bounding box for model instances in libgdx?

Tags:

android

libgdx

I have create a Model (a box) and 100 instances of it, moved around in the world. They get rendered where they are expected to.

I'm now trying to implement ray picking but I have found that all 100 instances return the same bounding box of the original model. Why isn't the actual bounding box calculated for each instance?

Creating model and instances:

public static void createModel() {
   ModelBuilder modelBuilder = new ModelBuilder();
   modelBuilder.begin();
   MeshPartBuilder tileBuilder;
   tileBuilder = modelBuilder.part("top", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal | Usage.TextureCoordinates, new Material(ColorAttribute.createDiffuse(Color.WHITE)));
   tileBuilder.rect(-0.45f, 0.1f, 0.45f,   0.45f, 0.1f, 0.45f,    0.45f, 0.1f, -0.45f,  -0.45f, 0.1f, -0.45f,  0f, 1f, 0f);
   tileBuilder = modelBuilder.part("bottom", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal, new Material(ColorAttribute.createDiffuse(Color.WHITE)));
   tileBuilder.rect(-0.45f, 0f, -0.45f,    0.45f, 0f, -0.45f,     0.45f, 0f, 0.45f,     
...
   modelTile = modelBuilder.end();
}

public void createModelInstance(com.badlogic.gdx.assets.AssetManager assetManager) {
  Texture texTile = assetManager.get("textures/" + textureFile, Texture.class);
  Material mat = new Material(TextureAttribute.createDiffuse(texTile));
  modelInstance = new ModelInstance(modelTile); 
  modelInstance.nodes.get(0).parts.get(0).material.set(mat);
}

Moving the model instance:

public void setCoordinates(boolean animate, float x, float y, float z) {
  modelInstance.transform.setToTranslation(x,y,z);
  modelInstance.calculateTransforms();
}

Ray picking attempt:

public boolean pickTile(int x, int y) {
  cam.update();
  Ray ray = cam.getPickRay(x, y);
  BoundingBox bb = new BoundingBox();
  for (int i=0;i<gameData.tiles.length;i++) {
    Log.i("ltower", "checking " + i);
    gameData.tiles[i].getModelInstance().calculateBoundingBox(bb);
Log.i("ltower", "BB: " + bb.getCenter().x + "," + bb.getCenter().y + "," + bb.getCenter().z);
    if (Intersector.intersectRayBoundsFast(ray, bb)) {
      gameData.tiles[i].select();
      return true;
    }
  }
  return false;
}

Log:

01-05 05:27:18.934: I/ltower(2175): checking 0
01-05 05:27:18.984: I/ltower(2175): BB: 0.0,0.05,0.0
01-05 05:27:19.024: I/ltower(2175): checking 1
01-05 05:27:19.024: I/ltower(2175): BB: 0.0,0.05,0.0
01-05 05:27:19.044: I/ltower(2175): checking 2
01-05 05:27:19.064: I/ltower(2175): BB: 0.0,0.05,0.0
01-05 05:27:19.064: I/ltower(2175): checking 3
01-05 05:27:19.064: I/ltower(2175): BB: 0.0,0.05,0.0
01-05 05:27:19.064: I/ltower(2175): checking 4
01-05 05:27:19.064: I/ltower(2175): BB: 0.0,0.05,0.0
01-05 05:27:19.064: I/ltower(2175): checking 5
01-05 05:27:19.104: I/ltower(2175): BB: 0.0,0.05,0.0
01-05 05:27:19.104: I/ltower(2175): checking 6
01-05 05:27:19.104: I/ltower(2175): BB: 0.0,0.05,0.0 
...
like image 559
Arthur Avatar asked Jan 05 '14 10:01

Arthur


1 Answers

Since you just create several instances of the same Model, they also have the same BoundingBox. The bounding box will be just a bounding box around the vertices of the model's local coordinate system.

That means that you need use BoundingBox.mul() to apply the model instance's position, scale and rotation to the bounding box.

like image 61
noone Avatar answered Sep 21 '22 09:09

noone