Ejemplo n.º 1
0
// Compute the OBB for a set of points relative to a transform matrix and see if it is smaller than the current best value. If
// so, return it.
static void
computeOBB(TheaArray<Vector3> const & points, CoordinateFrame3 const & cframe, OBB & current_best_result, bool overwrite)
{
  if (points.empty())
    return;

  Vector3 lo, hi;
  lo = hi = cframe.pointToObjectSpace(points[0]);

  Vector3 p;
  for (array_size_t i = 1; i < points.size(); ++i)
  {
    p = cframe.pointToObjectSpace(points[i]);
    lo = lo.min(p);
    hi = hi.max(p);
  }

  Vector3 e = hi - lo;
  double volume = e.x() * e.y() * e.z();
  if (overwrite || volume < current_best_result.volume)
  {
    Vector3 c  = 0.5f * (lo + hi);
    Vector3 he = 0.5f * e;
    current_best_result = OBB(c - he, c + he, cframe, volume);
  }
}
Ejemplo n.º 2
0
// A rather hacky way of forming a joint descriptor, suitable only for exact matches like we want here
void
accumGroupFeatures(MeshGroup const & mg, TheaArray<double> & features)
{
  for (MeshGroup::MeshConstIterator mi = mg.meshesBegin(); mi != mg.meshesEnd(); ++mi)
  {
    TheaArray<double> const & mf = (*mi)->getFeatures();
    if (features.empty())
      features.resize(mf.size());

    alwaysAssertM(mf.size() == features.size(), "Feature vectors have different sizes");

    for (array_size_t j = 0; j < features.size(); ++j)
      features[j] += mf[j];
  }

  for (MeshGroup::GroupConstIterator ci = mg.childrenBegin(); ci != mg.childrenEnd(); ++ci)
    accumGroupFeatures(**ci, features);
}
Ejemplo n.º 3
0
static void
computeBestFitOBB(TheaArray<Vector3> const & points, Box3 & result, bool has_up, Vector3 const & up)
{
  if (points.empty())
  {
    result = Box3();
    return;
  }
  else if (points.size() == 1)
  {
    result = Box3(AxisAlignedBox3(points[0]));
    return;
  }

  Vector3 centroid;
  CoordinateFrame3 cframe;

  if (has_up)
  {
    centroid = CentroidN<Vector3, 3>::compute(points.begin(), points.end());
    Vector3 u, v;
    up.createOrthonormalBasis(u, v);
    cframe = CoordinateFrame3::_fromAffine(AffineTransform3(basisMatrix(u, v, up), centroid));
  }
  else
  {
    Plane3 plane;
    LinearLeastSquares3<Vector3>::fitPlane(points.begin(), points.end(), plane, &centroid);
    planeToCFrame(plane, centroid, cframe);
  }

  OBB best_obb;
  computeOBB(points, cframe, best_obb, true);

  Matrix3 rot = Matrix3::rotationAxisAngle((has_up ? up : Vector3::unitY()), Math::degreesToRadians(10));
  for (int a = 10;  a < 180; a += 10)
  {
    cframe._setRotation(cframe.getRotation() * rot);
    computeOBB(points, cframe, best_obb, false);
  }

  result = Box3(AxisAlignedBox3(best_obb.lo, best_obb.hi), best_obb.cframe);
}