#include "gpuCacheSpatialGrid.h"
#include "gpuCacheSpatialGridWalker.h"
#include "gpuCacheIsectUtil.h"
#include <maya/MPointArray.h>
SpatialGrid::SpatialGrid(
const gridPoint3<int>& numVoxels
)
: fBounds(boundingBox),
fNumVoxels(numVoxels)
{
double minSize[3] = { 0.01, 0.01, 0.01 };
expandBBoxByPercentage( fBounds, 1.0, minSize );
fVoxelSizes[0] = fBounds.width() / fNumVoxels[0];
fVoxelSizes[1] = fBounds.height() / fNumVoxels[1];
fVoxelSizes[2] = fBounds.depth() / fNumVoxels[2];
if( fVoxelSizes[0] < 0.01 )
{
fVoxelSizes[0] = fBounds.width();
fNumVoxels[0] = 1;
}
if( fVoxelSizes[1] < 0.01 )
{
fVoxelSizes[1] = fBounds.height();
fNumVoxels[1] = 1;
}
if( fVoxelSizes[2] < 0.01 )
{
fVoxelSizes[2] = fBounds.depth();
fNumVoxels[2] = 1;
}
fVoxels.clear();
unsigned int totalVoxels = fNumVoxels[0] * fNumVoxels[1] * fNumVoxels[2];
for( unsigned int i = 0; i < totalVoxels; i++ )
{
fVoxels.push_back(NULL);
}
}
SpatialGrid::~SpatialGrid()
{
int numVoxels = fNumVoxels[0] * fNumVoxels[1] * fNumVoxels[2];
for( int v = 0; v < numVoxels; v++ )
{
if( fVoxels[v] != NULL )
{
delete fVoxels[v];
}
}
}
const gridPoint3<int>& SpatialGrid::getNumVoxels()
{
return fNumVoxels;
}
void SpatialGrid::bounds(
MPoint& lowerCorner,
MPoint& upperCorner )
{
lowerCorner = fBounds.min();
upperCorner = fBounds.max();
}
{
return fBounds;
}
int SpatialGrid::getLinearVoxelIndex( const gridPoint3<int>& index ) const
{
return index[2]*(fNumVoxels[0]*fNumVoxels[1])
+ index[1]*fNumVoxels[0]
+ index[0];
}
void
SpatialGrid::getVoxelRange(
gridPoint3<int>& minIndices,
gridPoint3<int>& maxIndices
) const
{
const MPoint& minPt = box.min();
const MPoint& maxPt = box.max();
getVoxelCoords( minPt, minIndices, NULL );
getVoxelCoords( maxPt, maxIndices, NULL );
}
void SpatialGrid::getVoxelCoords(
gridPoint3<int>& coords,
{
MPoint relPoint = point - fBounds.min();
for( int axis = 0; axis < 3; axis++ )
{
float voxSpace = relPoint[axis] / fVoxelSizes[axis];
coords[axis] = (int)floor( voxSpace );
if( coords[axis] < 0 )
{
coords[axis] = 0;
}
else if( coords[axis] >= fNumVoxels[axis] )
{
coords[axis] = fNumVoxels[axis]-1;
}
if( residuals != NULL )
{
(*residuals)[axis] = fVoxelSizes[axis]*(voxSpace-coords[axis]);
}
}
}
void SpatialGrid::expandBBoxByPercentage(
double percentage,
double min[3]
)
{
percentage += 1.0;
if( min != NULL )
{
if( w < min[0] )
{
w = min[0];
}
if( h < min[1] )
{
h = min[1];
}
if( d < min[2] )
{
d = min[2];
}
}
offset *= (0.5f * percentage);
}
void SpatialGrid::getClosestVoxelCoords(
gridPoint3<int>& coords) const
{
MPoint c1 = fBounds.min() +
MVector(fBounds.width()/4, fBounds.height()/4, fBounds.depth()/4);
MPoint c2 = fBounds.max() -
MVector(fBounds.width()/4, fBounds.height()/4, fBounds.depth()/4);
if(bounds.contains(point)){
relPoint = point - fBounds.min();
} else {
GPUCache::gpuCacheIsectUtil::getClosestPointOnBox(point, bounds, closestPoint);
relPoint = closestPoint - fBounds.min();
}
for( int axis = 0; axis < 3; axis++ )
{
float voxSpace = relPoint[axis] / fVoxelSizes[axis];
coords[axis] = (int)floor( voxSpace );
}
}
bool SpatialGrid::isValidVoxel(gridPoint3<int>& vox){
if(vox[0]>=0 && vox[0]<fNumVoxels[0] && vox[1]>=0 && vox[1]<fNumVoxels[1] && vox[2]>=0 && vox[2]<fNumVoxels[2])
return true;
return false;
}
SpatialGrid::getVoxelContents(
const gridPoint3<int>& index
)
{
int linearIndex = getLinearVoxelIndex( index );
if( fVoxels[linearIndex] == NULL )
{
}
return fVoxels[linearIndex];
}
float SpatialGrid::getMemoryFootprint()
{
int totalSize = 0;
int numVoxels = fNumVoxels[0]*fNumVoxels[1]*fNumVoxels[2];
for( int v = 0; v < numVoxels; v++ )
{
if( fVoxels[v] != NULL )
{
totalSize += fVoxels[v]->
length()*
sizeof(
unsigned int);
}
}
return ((float)totalSize)/1024.0f;
}
SpatialGridWalker SpatialGrid::getRayIterator(
{
return SpatialGridWalker( origin, direction, this );
}