Exemplo n.º 1
0
std::pair<bool, Real>
doPicking(const Ogre::Ray& localRay, const CollisionModel& collisionModel, CullingMode cullingMode)
{
    // Convert our ray to Opcode ray
    IceMaths::Ray world_ray(
        IceMaths::Point(localRay.getOrigin().x, localRay.getOrigin().y, localRay.getOrigin().z),
        IceMaths::Point(localRay.getDirection().x, localRay.getDirection().y, localRay.getDirection().z));

    // Be aware we store triangle as ccw in collision mode, and Opcode treat it as cw,
    // so need to inverse cull mode here.
    Opcode::CullMode cullMode;
    switch (cullingMode)
    {
    default:
    case CULL_NONE:
        cullMode = Opcode::CULLMODE_NONE;
        break;
    case CULL_CLOCKWISE:
        cullMode = Opcode::CULLMODE_CCW;
        break;
    case CULL_ANTICLOCKWISE:
        cullMode = Opcode::CULLMODE_CW;
        break;
    }

    // Cull mode callback for Opcode
    struct Local
    {
        static Opcode::CullMode cullModeCallback(udword triangle_index, void* user_data)
        {
            return (Opcode::CullMode) (int) user_data;
        }
    };

    std::pair<bool, Real> ret;

    // Do picking
    Opcode::CollisionFace picked_face;
    ret.first = Opcode::Picking(picked_face,
        world_ray, collisionModel.getOpcodeModel(), 0,
        0, FLT_MAX,
        world_ray.mOrig,
        &Local::cullModeCallback, (void*) (int) cullMode);
    ret.second = ret.first ? picked_face.mDistance : 0;

    return ret;
}
Exemplo n.º 2
0
void PLodNode::ray_test_impl(Ray const& ray,
                             int options,
                             Mask const& mask,
                             std::set<PickResult>& hits) {

  // first of all, check bbox
  auto box_hits(::gua::intersect(ray, bounding_box_));

  // ray did not intersect bbox -- therefore it wont intersect
  if (box_hits.first == Ray::END && box_hits.second == Ray::END) {
    return;
  }

  // return if only first object shall be returned and the current first hit
  // is in front of the bbox entry point and the ray does not start inside
  // the bbox
  if (options & PickResult::PICK_ONLY_FIRST_OBJECT && hits.size() > 0 &&
      hits.begin()->distance < box_hits.first && box_hits.first != Ray::END) {
    return;
  }

  // bbox is intersected, but check geometry only if mask tells us to check
  if (get_geometry_description() != "" && mask.check(get_tags())) {
    auto geometry(
        GeometryDatabase::instance()->lookup(get_geometry_description()));

    if (geometry) {
      Ray world_ray(ray);
      geometry->ray_test(world_ray, options, this, hits);
    }
  }

  for (auto child : get_children()) {
    child->ray_test_impl(ray, options, mask, hits);
  }
}