Пример #1
0
QBVHAccel::QBVHAccel(const unsigned int vCount, const unsigned int triangleCount, const Triangle *p, const Point *v, 
		u_int mp, u_int fst, u_int sf)  : Accellerator(vCount, triangleCount, p,v),fullSweepThreshold(fst),
		skipFactor(sf), maxPrimsPerLeaf(mp) {
	initialized = false;
	maxDepth = 0;
	int nPrims = triangleCount;
	vertices = v;
	triangles = p;

	// Temporary data for building
	u_int *primsIndexes = new u_int[nPrims + 3]; // For the case where
	// the last quad would begin at the last primitive
	// (or the second or third last primitive)

	// The number of nodes depends on the number of primitives,
	// and is bounded by 2 * nPrims - 1.
	// Even if there will normally have at least 4 primitives per leaf,
	// it is not always the case => continue to use the normal bounds.
	nNodes = 0;
	maxNodes = 1;
	for (u_int layer = ((nPrims + maxPrimsPerLeaf - 1) / maxPrimsPerLeaf + 3) / 4; layer != 1; layer = (layer + 3) / 4)
		maxNodes += layer;
	nodes = AllocAligned<QBVHNode>(maxNodes);
	for (u_int i = 0; i < maxNodes; ++i)
		nodes[i] = QBVHNode();

	// The arrays that will contain
	// - the bounding boxes for all triangles
	// - the centroids for all triangles	
	BBox *primsBboxes = new BBox[nPrims];
	Point *primsCentroids = new Point[nPrims];
	// The bouding volume of all the centroids
	BBox centroidsBbox;

	// Fill each base array
	for (u_int i = 0; i < triangleCount; ++i) {
		// This array will be reorganized during construction. 
		primsIndexes[i] = i;

		// Compute the bounding box for the triangle
		primsBboxes[i] = triangles[i].WorldBound(v);
		primsBboxes[i].Expand(RAY_EPSILON);
		primsCentroids[i] = (primsBboxes[i].pMin + primsBboxes[i].pMax) * .5f;

		// Update the global bounding boxes
		worldBound = Union(worldBound, primsBboxes[i]);
		centroidsBbox = Union(centroidsBbox, primsCentroids[i]);
	}

	// Arbitrarily take the last primitive for the last 3
	primsIndexes[nPrims] = nPrims - 1;
	primsIndexes[nPrims + 1] = nPrims - 1;
	primsIndexes[nPrims + 2] = nPrims - 1;

	// Recursively build the tree
	//LR_LOG(context, "Building QBVH, primitives: " << nPrims << ", initial nodes: " << maxNodes);

	nQuads = 0;
	BuildTree(0, nPrims, primsIndexes, primsBboxes, primsCentroids,worldBound, centroidsBbox, -1, 0, 0);

	prims = AllocAligned<QuadTriangle>(nQuads);
	nQuads = 0;
	PreSwizzle(0, primsIndexes);

	//LR_LOG(context, "QBVH completed with " << nNodes << "/" << maxNodes << " nodes");
	//LR_LOG(context, "Total QBVH memory usage: " << nNodes * sizeof(QBVHNode) / 1024 << "Kbytes");
	//LR_LOG(context, "Total QBVH QuadTriangle count: " << nQuads);

	// Release temporary memory
	delete[] primsBboxes;
	delete[] primsCentroids;
	delete[] primsIndexes;
}
Пример #2
0
void QBVHAccel::Init(const Mesh *m) {
  assert (!initialized);

  mesh = m;
  const unsigned int totalTriangleCount = mesh->GetTotalTriangleCount();

  // Temporary data for building
  u_int *primsIndexes = new u_int[totalTriangleCount + 3]; // For the case where
  // the last quad would begin at the last primitive
  // (or the second or third last primitive)

  // The number of nodes depends on the number of primitives,
  // and is bounded by 2 * nPrims - 1.
  // Even if there will normally have at least 4 primitives per leaf,
  // it is not always the case => continue to use the normal bounds.
  nNodes = 0;
  maxNodes = 1;
  for (u_int layer = ((totalTriangleCount + maxPrimsPerLeaf - 1)
      / maxPrimsPerLeaf + 3) / 4; layer != 1; layer = (layer + 3) / 4)
    maxNodes += layer;
  nodes = AllocAligned<QBVHNode> (maxNodes);
  for (u_int i = 0; i < maxNodes; ++i)
    nodes[i] = QBVHNode();

  // The arrays that will contain
  // - the bounding boxes for all triangles
  // - the centroids for all triangles
  BBox *primsBboxes = new BBox[totalTriangleCount];
  Point *primsCentroids = new Point[totalTriangleCount];
  // The bouding volume of all the centroids
  BBox centroidsBbox;

  const Point *verts = mesh->GetVertices();
  const Triangle *triangles = mesh->GetTriangles();

  // Fill each base array
  for (u_int i = 0; i < totalTriangleCount; ++i) {
    // This array will be reorganized during construction.
    primsIndexes[i] = i;

    // Compute the bounding box for the triangle
    primsBboxes[i] = triangles[i].WorldBound(verts);
    primsBboxes[i].Expand(RAY_EPSILON);
    primsCentroids[i] = (primsBboxes[i].pMin + primsBboxes[i].pMax) * .5f;

    // Update the global bounding boxes
    worldBound = Union(worldBound, primsBboxes[i]);
    centroidsBbox = Union(centroidsBbox, primsCentroids[i]);
  }

  // Arbitrarily take the last primitive for the last 3
  primsIndexes[totalTriangleCount] = totalTriangleCount - 1;
  primsIndexes[totalTriangleCount + 1] = totalTriangleCount - 1;
  primsIndexes[totalTriangleCount + 2] = totalTriangleCount - 1;

  // Recursively build the tree
  LR_LOG( "Building QBVH, primitives: " << totalTriangleCount << ", initial nodes: " << maxNodes);

  nQuads = 0;
  BuildTree(0, totalTriangleCount, primsIndexes, primsBboxes, primsCentroids,
      worldBound, centroidsBbox, -1, 0, 0);

  prims = AllocAligned<QuadTriangle> (nQuads);
  nQuads = 0;
  PreSwizzle(0, primsIndexes);

  LR_LOG( "QBVH completed with " << nNodes << "/" << maxNodes << " nodes");
  LR_LOG( "Total QBVH memory usage: " << nNodes * sizeof(QBVHNode) / 1024 << "Kbytes");
  LR_LOG( "Total QBVH QuadTriangle count: " << nQuads);
  LR_LOG( "Max. QBVH Depth: " << maxDepth);

  // Release temporary memory
  delete[] primsBboxes;
  delete[] primsCentroids;
  delete[] primsIndexes;

  initialized = true;
}