bool ATOM_AABBTreeBuilder::buildFromPrimitives (ATOM_AABBTree *tree, ATOM_AABBTree::PrimitiveType prim, const ATOM_Vector3f *verts, unsigned numVerts, const unsigned short *indices, unsigned numPrimitives, unsigned maxLeafPrimitiveCount, int maxDepth) { if (!numPrimitives) { return false; } reset (); _vertices.resize (numVerts); memcpy (&_vertices[0], verts, sizeof(ATOM_Vector3f) * numVerts); unsigned numIndices = calcIndexCount (prim, numPrimitives); _indices.resize (numIndices); memcpy (&_indices[0], indices, sizeof(unsigned short) * numIndices); _extractedIndices.resize (numPrimitives * 3); WorkingItem *item = new WorkingItem; item->primitives.resize (numPrimitives); item->depth = 0; _items.push_back (item); for (unsigned i = 0; i < numPrimitives; ++i) { item->primitives[i] = i; getPrimitive (i, indices, prim, &_extractedIndices[i*3]); } item->left = -1; item->right = -1; int off = 0; for (;;) { workOnItem (prim, *_items[off++], maxLeafPrimitiveCount, maxDepth - 1); if (off == _items.size()) { break; } } return buildFinalTree (tree, prim); }
AABBTreePoly* AABBTreePolyBuilder::buildFromPolys(const Polygon *_pols, int _nbPolys, const Vec3f *_points, int _nbPoints, int _leafDepth, Monitor *_moni) { int i; tree_ = new AABBTreePoly(_leafDepth); tree_->points_ = new Vec3f[_nbPoints]; tree_->nbPoints_ = _nbPoints; for (i = 0; i < _nbPoints; i++) tree_->points_[i] = _points[i]; WorkingItem *item = new WorkingItem(); for (i = 0; i < _nbPolys; i++) item->pols.add( (Polygon*) &_pols[i]); item->left = -1; item->right = -1; items_.add(item); int off = 0; while(true) { WorkingItem &it = *items_[off]; workOnItem(it, _leafDepth); off++; int size = items_.size(); if (off == size) break; } build(_moni); delete item; return tree_; }
AABBTreeSphere* AABBTreeSphere_Builder::build(int nbSpheres, const Sphere *spheres, int leafDepth, Monitor *moni) { int i, j; tree_ = new AABBTreeSphere(leafDepth); // Build the root node WorkingItem *item = new WorkingItem(); for (i = 0; i < nbSpheres; i++) item->spheres.add( spheres[i] ); item->left = -1; item->right = -1; items_.add(item); int off = 0; while(true) { WorkingItem &it = *items_[off]; workOnItem(it, leafDepth); off++; int size = items_.size(); if (off == size) break; } // Now we have a bastard working tree, let's build the final clean one... int *ln = new int[items_.size()]; int nbNodes = 0; int nbLeafs = 0; for (i = 0; i < items_.size(); i++) { WorkingItem &it = *items_[i]; if (it.left == -1 && it.right == -1) ln[i] = nbLeafs++; else ln[i] = nbNodes++; } tree_->root_ = new AABBTreeNode[nbNodes]; tree_->leafs_ = new AABBTreeSphereLeaf[nbLeafs]; tree_->nbNodes_ = nbNodes; tree_->nbLeafs_ = nbLeafs; if (moni) moni->write("Building the final clean tree"); for (i = 0; i < items_.size(); i++) { if (moni) moni->setProgress(i, items_.size()); WorkingItem &it = *items_[i]; if (it.left == -1 && it.right == -1) { int indexLeaf = ln[i]; AABBTreeSphereLeaf *sl = (AABBTreeSphereLeaf*) tree_->leafs_; sl += indexLeaf; sl->aabb = it.aabb; sl->left = NULL; sl->right = NULL; int nbSpheres = it.spheres.size(); sl->nbSpheres = nbSpheres; sl->spheres = new Sphere[nbSpheres]; for (j = 0; j < nbSpheres; j++) { Sphere *sp = (Sphere*) &sl->spheres[j]; *sp = it.spheres[j]; } } else { int nodeIndex = ln[i]; AABBTreeNode *node = &tree_->root_[nodeIndex]; node->aabb = it.aabb; if (it.left != -1) { WorkingItem *item = items_[it.left]; if (item->left == -1 && item->right == -1) { AABBTreeSphereLeaf *leaf = (AABBTreeSphereLeaf*) tree_->leafs_; node->left = leaf + ln[it.left]; } else { node->left = tree_->root_ + ln[it.left]; } } else node->left = NULL; if (it.right != -1) { WorkingItem *item = items_[it.right]; if (item->left == -1 && item->right == -1) { AABBTreeSphereLeaf *leaf = (AABBTreeSphereLeaf*) tree_->leafs_; node->right = leaf + ln[it.right]; } else { node->right = tree_->root_ + ln[it.right]; } } else node->right = NULL; } } if (moni) moni->write("Freeing temporary buffer"); delete [] ln; delete item; items_.clear(); if (moni) moni->write("Done."); return tree_; }