Shape tracability and data association

help

#1

Hi there. In a first time, I would like to thank you for sharing such an important code with the community, as it’s a very important building block for a lot of Rust potential uses.

In a second time, I would like to share with you an interrogation on how to use ncollide in a case that seems to me to be a basic one (I may be wrong about it, feel free to push me in the right direction if you feel like it).

Here is the thing. I’m trying to handle simple 2d overing detection on a 2.5d game, ncollide seems to be the right way to do it in a efficient and maintainable way to do that.

My approach is the following: having a way to know where are each «selectable» hexagon on the screen, I’m building a static BVT and then query it with the cursor position, then check between the potential candidate which are truely inside a given hexagon.

Here is a simple test I made (with only one hexagon). And if it work pretty well (the shape is correcly approximed, then checked etc.) exept that I can’t see how to use the resulting data. What I mean is that I get a Shape trait objet, that I can eventually convert to a ConvexPolygon, but I can’t see how I can associate things like an id (like an entity id) to it, and thus be able to exploit the computation result.

The only solution appearing to me is to make my own Shape type, but it seems overly convoluted as such a shape/world-data association seem to me to be one of the most basic usecase of such a library (I may be wrong).

 fn translate(&self, p_event: &PointerEvent) -> Option<HexOverEvent>
  {
    let points = [Point2::new(0.6, 23.9),
                  Point2::new(7.5, 17.1),
                  Point2::new(16.8, 20.9),
                  Point2::new(19.3, 27.5),
                  Point2::new(12.5, 32.4),
                  Point2::new(3.2, 30.5)];

    let hexagon =
      ConvexPolygon::try_from_points(&points).expect("Convex hull computation failed.");
    let bv = bounding_volume::bounding_sphere(&hexagon, &Isometry2::identity());
    let mut lst = Vec::new();
    lst.push((&hexagon, bv));
    use std::sync::Arc;

    let bvt = BVT::new_balanced(lst);

    let mut potentially_concerned = Vec::new();

    let pointer =
      &Point::new(p_event.x as f32 / 10. + self.camera_position.x / 10. - 0.6,
                  p_event.y as f32 / 10. + self.camera_position.y / 10. + 24.0);
    {
      let mut visitor =
        PointInterferencesCollector::new(pointer, &mut potentially_concerned);
      bvt.visit(&mut visitor);
    }

    for shape in potentially_concerned
    {
      if shape.contains_point(&Isometry2::identity(), pointer)
      {
        println!("{:?}", shape); // having a only shape here does not allow me to exploit the information.
                                           // in a meaningful way. Or does it?
      }
      else
      {
        println!("nope");
      }
    }

  Some(HexOverEvent {})
}

So, I would be glad to have some tips from you to put me back on track :slight_smile:
Have a nice Sunday.


#2

Hi! Glad ncollide can be useful :slight_smile:

In the BVT, each bounding volume can be associated to any kind of data as long as they implement Clone. So you could very well add the extra information you need to the Vec you use for initializing the BVT:

let mut lst = Vec::new();
lst.push(((&hexagon, some_ID_or_anything), bv));

Here, each bv is associated with a tuple containing the &Shape and any kind of data you need.
Then your loop could look like this:

for (shape, data) in potentially_concerned
{
  if shape.contains_point(&Isometry2::identity(), pointer)
  {
    // You have both the shape and the associated data here.
  }
  else
  {
    println!("nope");
  }
}

#3

Oh.

well, that’s a good way of doing that :smiley: Thank you.

I was missleaded by the example from the user guide. I’ll try to contribute to the documentation in the future :slight_smile: