Ejemplo n.º 1
0
bool Opcode::CompleteBoxPruning(udword nb, const AABB** array, Pairs& pairs, const Axes& axes)
{
	// Checkings
	if(!nb || !array)	return false;

	// Catch axes
	udword Axis0 = axes.mAxis0;
	udword Axis1 = axes.mAxis1;
	udword Axis2 = axes.mAxis2;

#ifdef ORIGINAL_VERSION
	// Allocate some temporary data
//	float* PosList = new float[nb];
	float* PosList = new float[nb+1];

	// 1) Build main list using the primary axis
	for(udword i=0;i<nb;i++)	PosList[i] = array[i]->GetMin(Axis0);
PosList[nb++] = MAX_FLOAT;

	// 2) Sort the list
	PRUNING_SORTER* RS = GetCompletePruningSorter();
	const udword* Sorted = RS->Sort(PosList, nb).GetRanks();

	// 3) Prune the list
	const udword* const LastSorted = &Sorted[nb];
	const udword* RunningAddress = Sorted;
	udword Index0, Index1;
	while(RunningAddress<LastSorted && Sorted<LastSorted)
	{
		Index0 = *Sorted++;

//		while(RunningAddress<LastSorted && PosList[*RunningAddress++]<PosList[Index0]);
		while(PosList[*RunningAddress++]<PosList[Index0]);

		if(RunningAddress<LastSorted)
		{
			const udword* RunningAddress2 = RunningAddress;

//			while(RunningAddress2<LastSorted && PosList[Index1 = *RunningAddress2++]<=array[Index0]->GetMax(Axis0))
			while(PosList[Index1 = *RunningAddress2++]<=array[Index0]->GetMax(Axis0))
			{
//				if(Index0!=Index1)
//				{
					if(array[Index0]->Intersect(*array[Index1], Axis1))
					{
						if(array[Index0]->Intersect(*array[Index1], Axis2))
						{
							pairs.AddPair(Index0, Index1);
						}
					}
//				}
			}
		}
	}

	DELETEARRAY(PosList);
#endif

#ifdef JOAKIM
	// Allocate some temporary data
//	float* PosList = new float[nb];
	float* MinList = new float[nb+1];

	// 1) Build main list using the primary axis
	for(udword i=0;i<nb;i++)	MinList[i] = array[i]->GetMin(Axis0);
	MinList[nb] = MAX_FLOAT;

	// 2) Sort the list
	PRUNING_SORTER* RS = GetCompletePruningSorter();
	udword* Sorted = RS->Sort(MinList, nb+1).GetRanks();

	// 3) Prune the list
//	const udword* const LastSorted = &Sorted[nb];
//	const udword* const LastSorted = &Sorted[nb-1];
	const udword* RunningAddress = Sorted;
	udword Index0, Index1;

//	while(RunningAddress<LastSorted && Sorted<LastSorted)
//	while(RunningAddress<LastSorted)
	while(RunningAddress<&Sorted[nb])
//	while(Sorted<LastSorted)
	{
//		Index0 = *Sorted++;
		Index0 = *RunningAddress++;

//		while(RunningAddress<LastSorted && PosList[*RunningAddress++]<PosList[Index0]);
//		while(PosList[*RunningAddress++]<PosList[Index0]);
//RunningAddress = Sorted;
//		if(RunningAddress<LastSorted)
		{
			const udword* RunningAddress2 = RunningAddress;

//			while(RunningAddress2<LastSorted && PosList[Index1 = *RunningAddress2++]<=array[Index0]->GetMax(Axis0))

//			float CurrentMin = array[Index0]->GetMin(Axis0);
			float CurrentMax = array[Index0]->GetMax(Axis0);

			while(MinList[Index1 = *RunningAddress2] <= CurrentMax)
//			while(PosList[Index1 = *RunningAddress] <= CurrentMax)
			{
//				if(Index0!=Index1)
//				{
					if(array[Index0]->Intersect(*array[Index1], Axis1))
					{
						if(array[Index0]->Intersect(*array[Index1], Axis2))
						{
							pairs.AddPair(Index0, Index1);
						}
					}
//				}

				RunningAddress2++;
//				RunningAddress++;
			}
		}
	}

	DELETEARRAY(MinList);
#endif

	return true;
}
/**
 *	Complete box pruning.
 *  Returns a list of overlapping pairs of boxes, each box of the pair
 *  belongs to the same set.
 *  NOTE: code uses floats instead of dReals because Opcode's radix sort
 *  is optimized for floats :)
 *
 *	@param	count	[in] number of boxes.
 *	@param	geoms	[in] geoms of boxes.
 *	@param	pairs	[out] array of overlapping pairs.
 *	@param	axes	[in] projection order (0,2,1 is often best).
 *	@return	true	If success.
 */
static bool complete_box_pruning( int count, const dxGeom** geoms, Pairs& pairs, const Axes& axes )
{
    // Checks
    if (!count || !geoms)
        return false;

    // Catch axes
    udword Axis0 = axes.mAxis0;
    udword Axis1 = axes.mAxis1;
    udword Axis2 = axes.mAxis2;

    // Axis indices into geom's aabb are: min=idx, max=idx+1
    udword ax0idx = Axis0*2;
    udword ax1idx = Axis1*2;
    udword ax2idx = Axis2*2;

    // Allocate some temporary data
    // TBD: persistent allocation between queries?
    float* PosList = new float[count+1];

    // 1) Build main list using the primary axis
    for( int i = 0; i < count; ++i )
        PosList[i] = (float)geoms[i]->aabb[ax0idx];
    PosList[count++] = MAX_FLOAT;

    // 2) Sort the list
    PRUNING_SORTER* RS = get_pruning_sorter();
    const udword* Sorted = RS->Sort(PosList, count).GetRanks();

    // 3) Prune the list
    const udword* const LastSorted = &Sorted[count];
    const udword* RunningAddress = Sorted;
    udword Index0, Index1;
    while( RunningAddress < LastSorted && Sorted < LastSorted ) {
        Index0 = *Sorted++;

        while( PosList[*RunningAddress++] < PosList[Index0] ) {
            // empty, the loop just advances RunningAddress
        }

        if( RunningAddress < LastSorted ) {
            const udword* RunningAddress2 = RunningAddress;

            float idx0ax0max = (float)geoms[Index0]->aabb[ax0idx+1];
            float idx0ax1max = (float)geoms[Index0]->aabb[ax1idx+1];
            float idx0ax2max = (float)geoms[Index0]->aabb[ax2idx+1];
            while( PosList[Index1 = *RunningAddress2++] <= idx0ax0max ) {
//				if(Index0!=Index1)
//				{
                const dReal* aabb0 = geoms[Index0]->aabb;
                const dReal* aabb1 = geoms[Index1]->aabb;
                if( idx0ax1max < (float)aabb1[ax1idx] || (float)aabb1[ax1idx+1] < (float)aabb0[ax1idx] ) {
                    // no intersection
                } else {
                    if( idx0ax2max < (float)aabb1[ax2idx] || (float)aabb1[ax2idx+1] < (float)aabb0[ax2idx] ) {
                        // no intersection
                    } else {
                        // yes! :)
                        pairs.AddPair( Index0, Index1 );
                    }
                }
//				}
            }
        }
    }
    DELETEARRAY(PosList);
    return true;
}