示例#1
0
bool ot_dist_traverse(OT_NODE *subtree, const Vector3d& point, int bounce_depth, bool (*function)(OT_BLOCK *block, void *handle1), void *handle)
// only those blocks with this recur depth
{
#ifdef RADSTATS
	extern long ot_seenodecount, ot_seeblockcount;
#endif

	int i;
	bool oksofar;
	OT_NODE *this_node;
	OT_BLOCK *this_block;

#ifdef RADSTATS
	ot_seenodecount++;
#endif

	// First, recurse to the child nodes
	oksofar = true;
	for (i = 0; i < 8 && oksofar; i++)
	{     // for each potential kid
		this_node = subtree->Kids[i];
		if (this_node != NULL)
		{   // ...which exists
			if (ot_point_in_node(point, &this_node->Id))
			{ // ...and in range
				if(!ot_dist_traverse(this_node, point, bounce_depth, function, handle))
					oksofar = false;
			}
		}
	}

	// Now, call the specified routine for each data block hung off this tree
	// node

	// if ( ot_point_in_node(point, &subtree->Id) )
	{
		this_block = subtree->Values;
		while (oksofar && (this_block != NULL))
		{
#ifdef RADSTATS
			if (subtree->Id.Size < 100 || subtree->Id.Size > 140 )
			{
				Debug_Info("bounds error, unreasonable size %d\n", subtree->Id.Size);
			}
			ot_seeblockcount++;
#endif
			if ((int)this_block->Bounce_Depth == bounce_depth)
			{
				//oksofar = (*function) (this_block, handle);
				if (!( (*function) (this_block, handle)))
					oksofar = false;
			}
			this_block = this_block->next;
		}
	}

	return oksofar;
}
示例#2
0
文件: octree.cpp 项目: hjw3001/povray
void ot_index_box(const Vector3d& min_point, const Vector3d& max_point, OT_ID *id)
{
// TODO OPTIMIZE

    DBL dx, dy, dz, desiredSize;
    DBL bsized, maxord;
    POW2OP_DECLARE()

    // Calculate the absolute minimum required size of the node, assuming it is perfectly centered within the node;
    // Node size must be a power of 2, and be large enough to accomodate box's biggest dimensions with maximum overhang to all sides

    // compute ideal size of the node for a perfect fit without any overhang
    dx = max_point.x() - min_point.x();
    dy = max_point.y() - min_point.y();
    dz = max_point.z() - min_point.z();
    desiredSize = max3(dx, dy, dz);

    // compute ideal size of the node for a perfect fit with full overhang to all sides
    // desiredSize /= (1 + 2 * 0.5);

    // compute best-matching power-of-two size for a perfect fit with overhang
    // (Note: theoretically this might pick a size larger than required if desiredSize is already a power of two)
    // desiredSize *= 2.0;
    POW2OP_FLOOR(bsized,desiredSize)

    // avoid divisions by zero
    if(bsized == 0.0)
        bsized = 1.0;

#ifdef SAFE_METHOD

    // This block checks for the case where the node id would cause integer
    // overflow, since it is a small buffer far away
    maxord = max3(fabs(min_point[X]), fabs(min_point[Y]), fabs(min_point[Z]));
    maxord += OT_BIAS;
    while (maxord / bsized > 1000000000.0)
    {
#ifdef RADSTATS
        overflows++;
#endif
        bsized *= 2.0;
    }
#endif // SAFE_METHOD

    // The node we chose so far would be ideal for a box of identical size positioned at the node's center,
    // but the actual box is probably somewhat off-center and therefore may have excessive overhang in some directions;
    // check and possibly fix this.

    Vector3d center = (min_point + max_point) / 2;
    id->x = (int) floor((center[X] + OT_BIAS) / bsized);
    id->y = (int) floor((center[Y] + OT_BIAS) / bsized);
    id->z = (int) floor((center[Z] + OT_BIAS) / bsized);
    POW2OP_ENCODE(id->Size, bsized)

#ifdef RADSTATS
    thisloops = 0;
#endif
    while (!ot_point_in_node(min_point, id) || !ot_point_in_node(max_point, id))
    {
        // Debug_Info("looping %d,%d,%d,%d  min=%d, max=%d\n", test_id.x, test_id.y,
        // test_id.z, test_id.Size, ot_point_in_node(min_point, &test_id),
        // ot_point_in_node(max_point, &test_id));
        ot_parent(id, id);
#ifdef RADSTATS
        totloops++;
        thisloops++;
#endif
    }
#ifdef RADSTATS
    if (thisloops < minloops)
        minloops = thisloops;
    if (thisloops > maxloops)
        maxloops = thisloops;
#endif

#ifdef OT_DEBUG
    if (id->Size > 139)
    {
        Debug_Info("unusually large id, maxdel=%.4f, bsized=%.4f, isize=%d\n",
                   maxdel, bsized, id->Size);
    }
#endif
}