void KdTreeBuilder::BuildNode(const BoundingBox_f& nodeBounds,
                              const int32_t* nodeTriangles,
                              int32_t nodeTrianglesCount, int depth,
                              int32_t* triangles0, int32_t* triangles1)
{
  if (nodes.size() >= KdTree::Node::maxNodesCount)
    RuntimeError("maximum number of KdTree nodes has been reached: " +
                 std::to_string(KdTree::Node::maxNodesCount));

  // check if leaf node should be created
  if (nodeTrianglesCount <= buildParams.leafTrianglesLimit || depth == 0) {
    CreateLeaf(nodeTriangles, nodeTrianglesCount);
    buildStats.NewLeaf(nodeTrianglesCount, buildParams.maxDepth - depth);
    return;
  }

  // select split position
  auto split = SelectSplit(nodeBounds, nodeTriangles, nodeTrianglesCount);
  if (split.edge == -1) {
    CreateLeaf(nodeTriangles, nodeTrianglesCount);
    buildStats.NewLeaf(nodeTrianglesCount, buildParams.maxDepth - depth);
    return;
  }
  float splitPosition = edgesBuffer[split.edge].positionOnAxis;

  // classify triangles with respect to split
  int32_t n0 = 0;
  for (int32_t i = 0; i < split.edge; i++) {
    if (edgesBuffer[i].IsStart())
      triangles0[n0++] = edgesBuffer[i].GetTriangleIndex();
  }

  int32_t n1 = 0;
  for (int32_t i = split.edge + 1; i < 2 * nodeTrianglesCount; i++) {
    if (edgesBuffer[i].IsEnd())
      triangles1[n1++] = edgesBuffer[i].GetTriangleIndex();
  }

  // add interior node and recursively create children nodes
  auto thisNodeIndex = static_cast<int32_t>(nodes.size());
  nodes.push_back(KdTree::Node());

  BoundingBox_f bounds0 = nodeBounds;
  bounds0.maxPoint[split.axis] = splitPosition;
  BuildNode(bounds0, triangles0, n0, depth - 1, triangles0, triangles1 + n1);

  auto aboveChild = static_cast<int32_t>(nodes.size());
  nodes[thisNodeIndex].InitInteriorNode(split.axis, aboveChild, splitPosition);

  BoundingBox_f bounds1 = nodeBounds;
  bounds1.minPoint[split.axis] = splitPosition;
  BuildNode(bounds1, triangles1, n1, depth - 1, triangles0, triangles1);
}
Example #2
0
void
MergeLocalParticles (long my_id, particle **p_array, long num_of_particles, box *pb)
{
   particle *(p_dist)[NUM_OFFSPRING][MAX_PARTICLES_PER_BOX];
   long num_p_dist[NUM_OFFSPRING];
   box *child;
   long success;
   long i;

   SplitParticles(p_array, num_of_particles,
		  (particle **) p_dist, num_p_dist, pb);
   for (i= 0; i < NUM_OFFSPRING; i++) {
      if (num_p_dist[i] > 0) {
	 child = pb->children[i];
	 if (child == NULL) {
	    child = CreateLeaf(my_id, pb, i, p_dist[i], num_p_dist[i]);
	    success = InsertBoxInGrid(my_id, child, pb);
	 }
	 else {
	    if (child->type == PARENT) {
	       MergeLocalParticles(my_id, p_dist[i], num_p_dist[i], child);
	       success = TRUE;
	    }
	    else {
	       success = RemoveBoxFromGrid(child, pb);
	       if (success == TRUE) {
		  InsertParticlesInLeaf(my_id, p_dist[i], num_p_dist[i], child);
		  success = InsertBoxInGrid(my_id, child, pb);
	       }
	       else
		  child = CreateLeaf(my_id, pb, i, p_dist[i], num_p_dist[i]);
	    }
	 }
	 if (success == FALSE) {
	    MLGHelper(my_id, child, pb->children[child->child_num], pb);
	 }
      }
   }
}
Example #3
0
Plant::Plant(float iter) {
	if (!cylinder)
		CreateBranch();
	if (!leaf)
		CreateLeaf();
	if (!sphere)
		CreateSphere();

	branchLength = iter;

	growRate = 0.07f;
	branches = 3;

	memUsage = sizeof(*leaf) + sizeof(*cylinder) + sizeof(*sphere);

	trunk = new SceneNode();
	trunk->SetMesh(cylinder);
	trunk->SetModelScale(Vector3(0,0,0));
	trunk->SetTransform(Matrix4::Translation(Vector3(0, 0, 0)));
	memUsage += sizeof(*trunk);
	AddChild(trunk);

	CreateTree(trunk, branchLength);
}