Пример #1
0
static double squaredDistanceToAABB(const QVector3D& point,
    const AxisAlignedBox& box) {
  const QVector3D center = (box.Max() + box.Min()) / 2;
  const QVector3D half_sz = (box.Max() - box.Min()) / 2;
  const QVector3D vec(max(0.0, fabs(center.x() - point.x()) - half_sz.x()),
                      max(0.0, fabs(center.y() - point.y()) - half_sz.y()),
                      max(0.0, fabs(center.z() - point.z()) - half_sz.z()));
  return vec.lengthSquared();
}
Пример #2
0
bool SelectionQuery::Intersection(const AxisAlignedBox& box,
    const QVector3D& ray_start, const QVector3D& ray_dir, double* result) {
  const QVector3D& bmin = box.Min();
  const QVector3D& bmax = box.Max();
  const double inv_x = 1 / ray_dir.x();
  const double inv_y = 1 / ray_dir.y();
  const double inv_z = 1 / ray_dir.z();
  const double tx1 = (bmin.x() - ray_start.x()) * inv_x;
  const double tx2 = (bmax.x() - ray_start.x()) * inv_x;

  double tmin = std::min(tx1, tx2);
  double tmax = std::max(tx1, tx2);

  const double ty1 = (bmin.y() - ray_start.y()) * inv_y;
  const double ty2 = (bmax.y() - ray_start.y()) * inv_y;

  tmin = std::max(tmin, std::min(ty1, ty2));
  tmax = std::min(tmax, std::max(ty1, ty2));

  const double tz1 = (bmin.z() - ray_start.z()) * inv_z;
  const double tz2 = (bmax.z() - ray_start.z()) * inv_z;

  tmin = std::max(tmin, std::min(tz1, tz2));
  tmax = std::min(tmax, std::max(tz1, tz2));

  if (tmax >= tmin && tmax > 0) {
    *result = std::max(0.0, std::min(tmin, tmax));
    return true;
  }
  return false;
}
Пример #3
0
bool Frustum::Intersects(const AxisAlignedBox& box) {
  const QVector3D& bmin = box.Min();
  const QVector3D& bmax = box.Max();
  for (const Plane& plane : planes_) {
    const QVector3D& normal = plane.Normal();
    const QVector3D test_point(
        normal.x() > 0 ? bmax.x() : bmin.x(),
        normal.y() > 0 ? bmax.y() : bmin.y(),
        normal.z() > 0 ? bmax.z() : bmin.z());
    if (plane.SignedDistance(test_point) < 0) {
      return false;
    }
  }
  return true;
}
Пример #4
0
void DrawContext::DrawBoundingBox(const AxisAlignedBox& box) {
  if (!bounding_box_node_) {
    StockResources stock(resources_);
    ShaderResource::Ptr shader =
      stock.Shader(StockResources::kUniformColorNoLighting);

    MaterialResource::Ptr material = resources_->MakeMaterial(shader);
    material->SetParam("color", 0.0f, 1.0f, 0.0f, 1.0f);

    GeometryResource::Ptr geometry = resources_->MakeGeometry();
    GeometryData gdata;
    gdata.gl_mode = GL_LINES;
    gdata.vertices = {
      { QVector3D(0, 0, 0) },
      { QVector3D(0, 1, 0) },
      { QVector3D(1, 1, 0) },
      { QVector3D(1, 0, 0) },
      { QVector3D(0, 0, 1) },
      { QVector3D(0, 1, 1) },
      { QVector3D(1, 1, 1) },
      { QVector3D(1, 0, 1) },
    };
    gdata.indices = {
      0, 1, 1, 2, 2, 3, 3, 0,
      4, 5, 5, 6, 6, 7, 7, 4,
      0, 4, 1, 5, 2, 6, 3, 7 };
    geometry->Load(gdata);

    bounding_box_node_ = scene_->MakeDrawNode(nullptr);
    bounding_box_node_->Add(geometry, material);

    // hack to prevent the bounding box to appear during normal rendering
    bounding_box_node_->SetVisible(false);
  }

  bounding_box_node_->SetScale(box.Max() - box.Min());
  bounding_box_node_->SetTranslation(box.Min());
  model_mat_ = bounding_box_node_->WorldTransform();

  DrawDrawNode(bounding_box_node_);
}
Пример #5
0
void AxisAlignedBox::IncludeBox(const AxisAlignedBox& other) {
  IncludePoint(other.Min());
  IncludePoint(other.Max());
}