#ifndef _gpuCacheSpatialSubdivision
#define _gpuCacheSpatialSubdivision
#include "gpuCacheSample.h"
#include "gpuCacheSpatialGrid.h" 
#include "gpuCacheSpatialGridWalker.h" 
#include "gpuCacheIsectUtil.h"
namespace GPUCache {
typedef IndexBuffer::index_t index_t;
class ShapeNode;
class gpuCacheVoxelGrid;
class gpuCacheIsectAccelParams
{
public:
    
    
    gpuCacheIsectAccelParams();
    
    
    
    
    int operator==( const gpuCacheIsectAccelParams& rhs );
    int operator!=( const gpuCacheIsectAccelParams& rhs );
    
    
    
    
    
    
    
    
    
    
    
    
    
    static gpuCacheIsectAccelParams uniformGridParams( int divX = 10,
        int divY = 10,
        int divZ = 10 );
    
    static gpuCacheIsectAccelParams autoUniformGridParams();
    friend class gpuCacheSpatialSubdivision;
    
    enum
    {
        kUniformGrid,
        kAutoUniformGrid,
        kInvalid
    };
private:
    
    
    
    
    gpuCacheIsectAccelParams( int    alg, 
        int      divX,
        int      divY,
        int      divZ );
    int     fAlgorithm; 
    int         fDivX;      
    int         fDivY;      
    int         fDivZ;      
};
class gpuCacheSpatialSubdivision
{
public:
    
    
    
    gpuCacheSpatialSubdivision( unsigned int numTriangles, const index_t* srcTriangleVertIndices, const float* srcPositions,
        const MBoundingBox bounds, 
const gpuCacheIsectAccelParams& accelParams );
 
    
    
    ~gpuCacheSpatialSubdivision();
    
    
        const unsigned int numTriangles, 
        const index_t*  srcTriangleVertIndices, 
        const float*    srcPositions,   
        float           maxParam,
    
    
    
        const unsigned int numTriangles, 
        const index_t*  srcTriangleVertIndices, 
        const float*    srcPositions,   
        float           maxParam,
    
    
    bool closestPointToPoint(const unsigned int numTriangles, 
        const index_t*  srcTriangleVertIndices, 
        const float*    srcPositions,   
    
    
    void closestPointToPoint(const unsigned int numTriangles, 
        const index_t*  srcTriangleVertIndices, 
        const float*    srcPositions,   
    
    
    double getEdgeSnapPoint(const unsigned int numTriangles, 
        const index_t*  srcTriangleVertIndices, 
        const float*    srcPositions,
    
    
    double getEdgeSnapPoint(const unsigned int numTriangles, 
        const index_t*  srcTriangleVertIndices, 
        const float*    srcPositions,   
    
    
    
    bool matchesParams( const gpuCacheIsectAccelParams& accelParams );
    
    
    
    float getMemoryFootprint();
    
    
    
    float getBuildTime();
    
    
    MString getDescription( 
bool includeStats );
 
    
    
    
    static int totalNumActive();
    static int totalNumCreated();
    static float totalFootprints();
    static float totalBuildTimes();
    
    
    
    
    
    
    
    static void resetSystemStats(); 
private:
    
    
    void deleteVoxelGrid();
    
    
    gpuCacheIsectAccelParams    fAccelParams;
    gpuCacheVoxelGrid*          fVoxelGrid;
    
    
    
    
    float       fMemoryFootprint;
    float       fBuildTime;
    
    
    static int          fsTotalNumActiveSpatialSubdivisions;    
    static int          fsTotalNumCreatedSpatialSubdivisions;   
    static float            fsTotalMemoryFootprint; 
    static float            fsTotalBuildTime; 
    static float            fsPeakMemoryFootprint;
};
}
#endif