Beispiel #1
0
BBox BBoxIntersection(const BBox &b1, const BBox &b2) {
  BBox newbox(b1.dimension());

  ThrowAssert(b1.dimension() == b2.dimension());
  for (UInt i = 0; i < b1.dimension(); i++) {
    newbox.setMin(i, std::max(b1.getMin()[i], b2.getMin()[i]));
    newbox.setMax(i, std::min(b1.getMax()[i], b2.getMax()[i]));
  }

  newbox.checkEmpty();

  return newbox;
}
Beispiel #2
0
real FEdge::z_discontinuity() const
{
  if (!(getNature() & Nature::SILHOUETTE) && !(getNature() & Nature::BORDER)) {
    return 0;
  }

  BBox<Vec3r> box = ViewMap::getInstance()->getScene3dBBox();

  Vec3r bbox_size_vec(box.getMax() - box.getMin());
  real bboxsize = bbox_size_vec.norm();
  if (occludee_empty()) {
    // return FLT_MAX;
    return 1.0;
    // return bboxsize;
  }

#if 0
  real result;
  z_discontinuity_functor<SVertex> _functor;
  Evaluate<SVertex, z_discontinuity_functor<SVertex>>(&_functor, iCombination, result);
#endif
  Vec3r middle((_VertexB->point3d() - _VertexA->point3d()));
  middle /= 2;
  Vec3r disc_vec(middle - _occludeeIntersection);
  real res = disc_vec.norm() / bboxsize;

  return res;
  // return fabs((middle.z() - _occludeeIntersection.z()));
}
Beispiel #3
0
bool BBoxIntersect(const BBox &b1, const BBox &b2, double tol) {
  double newmin;
  double newmax;

  ThrowAssert(b1.dimension() == b2.dimension());
  for (UInt i = 0; i < b1.dimension(); i++) {
    newmin = std::max(b1.getMin()[i], b2.getMin()[i]);
    newmax = std::min(b1.getMax()[i], b2.getMax()[i]);
    if (newmin > (newmax+tol)) {
//std::cout << "fail, dim=" << i << " newmin=" << newmin << ", newmax=" << newmax << std::endl;
      return false;
    }
  }

  return true;
}
Beispiel #4
0
BBox BBoxParUnion(const BBox &b1) {
  double val, valres;
  BBox newbox(b1.dimension());


  for (UInt i = 0; i < b1.dimension(); i++) {
    // Find max 
    val = b1.getMax()[i];
    MPI_Allreduce(&val, &valres, 1, MPI_DOUBLE, MPI_MAX, Par::Comm());
    newbox.setMax(i, valres);
    val = b1.getMin()[i];
    MPI_Allreduce(&val, &valres, 1, MPI_DOUBLE, MPI_MIN, Par::Comm());
    newbox.setMin(i, valres);
  }

  newbox.checkEmpty();

  return newbox;
}
Beispiel #5
0
void Mesh::addTriangle(Triangle *t) {
    t->setPerVertexNormal(hasPerSurfaceNormal);
    t->setPerVertexMaterial(objectMaterial);
    triangles.push_back(t);

    BBox b = t->getBBox();
    Vect l0 = bbox.getMin();
    Vect l1 = b.getMin();
    l1.setX(min(l1.getX(), l0.getX()));
    l1.setY(min(l1.getY(), l0.getY()));
    l1.setZ(min(l1.getZ(), l0.getZ()));
    bbox.setMin(l1);

    Vect r0 = bbox.getMax();
    Vect r1 = b.getMax();
    r1.setX(max(r1.getX(), r0.getX()));
    r1.setY(max(r1.getY(), r0.getY()));
    r1.setZ(max(r1.getZ(), r0.getZ()));
    bbox.setMax(r1);
}
Beispiel #6
0
bool BBoxPointIn(const BBox &b, double point[], double tol) {
  for (UInt i = 0; i < b.dimension(); i++) {
    if (point[i] < b.getMin()[i] - tol || point[i] > b.getMax()[i] + tol) return false;
  }
  return true;
}
void KdTreeAccelerator::initializeInteriorNode(int node, const BBox& nodeBounds,
		const std::vector<BBox>& primitiveBounds, uint* overlappingPrimitives,
		int numOverlappingPrimitives, int depth, BoundEdge* edges[3],
		uint* prims0, uint* prims1, int badRefines)
{
	// Choose split axis and position for interior node
	int bestAxis = -1;
	int bestOffset = -1;
	float bestCost = INFINITY;
	float oldCost = m_intersectionCost * float(numOverlappingPrimitives);
	float totalSA = nodeBounds.getSurfaceArea();
	float invTotalSA = 1.f / totalSA;
	glm::vec3 d = nodeBounds.getMax() - nodeBounds.getMin();

	uint axis = nodeBounds.getAxisMaximumExtent();
	int retries = 0;

	// label for jump to choose another split
	retrySplit:

	// Initialize edges for choosen axis
	for(int i = 0; i < numOverlappingPrimitives; ++i)
	{
		int primitive = overlappingPrimitives[i];
		const BBox& bbox = primitiveBounds[primitive];
		edges[axis][2 * i + 0] = BoundEdge(bbox.getMin()[axis], primitive, true);
		edges[axis][2 * i + 1] = BoundEdge(bbox.getMax()[axis], primitive, false);
	}
	std::sort(&edges[axis][0], &edges[axis][2*numOverlappingPrimitives]);

	// Compute cost of all splits for the choosen axis to find best
	int nBelow = 0;
	int nAbove = numOverlappingPrimitives;
	for(int i = 0; i < 2 * numOverlappingPrimitives; ++i)
	{
		if(edges[axis][i].m_type == BoundEdge::END) --nAbove;

		float split = edges[axis][i].m_t;
		if(split > nodeBounds.getMin()[axis] && split < nodeBounds.getMax()[axis])
		{
			// compute cost of split at i-th edge
			uint oA0 = (axis + 1) % 3; // first other axis 
			uint oA1 = (axis + 2) % 3; // second other axis
			float belowSA = 2 * (d[oA0] * d[oA1] + (split - nodeBounds.getMin()[axis]) * (d[oA0] + d[oA1]));
			float aboveSA = 2 * (d[oA0] * d[oA1] + (nodeBounds.getMax()[axis] - split) * (d[oA0] + d[oA1]));
			float pBelow = belowSA * invTotalSA;
			float pAbove = aboveSA * invTotalSA;
			float bonus = (nAbove==0 || nBelow==0) ? m_emptyBonus : 0.f;
			float cost = m_intersectionCost * (1.f - bonus) * (pBelow * nBelow + pAbove * nAbove)
				+ m_traversalCost;

			// update best split if this split has lower costs
			if(cost < bestCost)
			{
				bestCost = cost;
				bestAxis = axis;
				bestOffset = i;
			}
		}

		if(edges[axis][i].m_type == BoundEdge::START) ++nBelow;
	}

	// try another axis of no good slit was found
	if(bestAxis == -1 && retries < 2)
	{
		++retries;
		axis = (axis + 1) % 3;
		goto retrySplit;
	}
	
	// Create lead if no good splits were found
	if (bestCost > oldCost) ++badRefines;
	if ((bestCost > 4.f * oldCost && numOverlappingPrimitives < 16) ||
		bestAxis == -1 || badRefines == 3) {
		m_nodes[node].initLeaf(overlappingPrimitives, numOverlappingPrimitives);
		return;
	}
	
	// Classify overlapping primitives with respect to split
	int n0 = 0, n1 = 0;
	for (int i = 0; i < bestOffset; ++i) {
		if (edges[bestAxis][i].m_type == BoundEdge::START) {
			prims0[n0++] = edges[bestAxis][i].m_primitive;
		}
	}
	for (int i = bestOffset+1; i < 2*numOverlappingPrimitives; ++i) {
		if (edges[bestAxis][i].m_type == BoundEdge::END) {
			prims1[n1++] = edges[bestAxis][i].m_primitive;
		}
	}

	// Recursively initialize child nodes
	float split = edges[bestAxis][bestOffset].m_t;
	glm::vec3 min = nodeBounds.getMax();
	glm::vec3 max = nodeBounds.getMin();
	min[bestAxis] = split;
	max[bestAxis] = split;
	BBox bounds0 = nodeBounds;
	BBox bounds1 = nodeBounds;
	bounds0.setMax(max);
	bounds1.setMin(min);

	buildTreeRecursive(node + 1, bounds0, primitiveBounds, prims0, n0, depth - 1, 
		edges, prims0, prims1 + numOverlappingPrimitives, badRefines);

	uint aboveChild = m_nextFreeNode;
	m_nodes[node].initInterior(bestAxis, aboveChild, split);

	buildTreeRecursive(aboveChild, bounds1, primitiveBounds, prims1, n1, depth - 1, 
		edges, prims0, prims1 + numOverlappingPrimitives, badRefines);
}
Beispiel #8
0
bool Ray::intersect(BBox& box, hpreal length){
    hpvec3 hitPoint;
    return checkLineBox(*(box.getMin()), *(box.getMax()), m_origin, m_origin + m_direction * length, hitPoint);
}