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); }
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); } } } }
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); }