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; }
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())); }
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; }
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; }
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); }
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); }
bool Ray::intersect(BBox& box, hpreal length){ hpvec3 hitPoint; return checkLineBox(*(box.getMin()), *(box.getMax()), m_origin, m_origin + m_direction * length, hitPoint); }