Beispiel #1
0
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_;
}