Moved the ambient occlusion calculation code from Thermite into PolyVox.

This commit is contained in:
David Williams 2011-01-16 16:26:10 +00:00
parent 8619b36b5f
commit e3dd07c216
7 changed files with 2367 additions and 0 deletions

View File

@ -15,6 +15,8 @@ SET(CORE_SRC_FILES
#Projects headers files
SET(CORE_INC_FILES
include/AmbientOcclusionCalculator.h
include/AmbientOcclusionCalculator.inl
include/Array.h
include/Array.inl
include/ArraySizes.h
@ -53,6 +55,8 @@ SET(CORE_INC_FILES
SET(IMPL_SRC_FILES
source/PolyVoxImpl/MarchingCubesTables.cpp
source/PolyVoxImpl/RandomUnitVectors.cpp
source/PolyVoxImpl/RandomVectors.cpp
source/PolyVoxImpl/Utility.cpp
)
@ -63,6 +67,8 @@ SET(IMPL_INC_FILES
include/PolyVoxImpl/Block.h
include/PolyVoxImpl/Block.inl
include/PolyVoxImpl/MarchingCubesTables.h
include/PolyVoxImpl/RandomUnitVectors.h
include/PolyVoxImpl/RandomVectors.h
include/PolyVoxImpl/SubArray.h
include/PolyVoxImpl/SubArray.inl
include/PolyVoxImpl/TypeDef.h

View File

@ -0,0 +1,55 @@
/*******************************************************************************
Copyright (c) 2005-2009 David Williams
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*******************************************************************************/
#ifndef __AmbientOcclusionCalculator_H__
#define __AmbientOcclusionCalculator_H__
#include "PolyVoxForwardDeclarations.h"
namespace PolyVox
{
template <typename VoxelType>
class AmbientOcclusionCalculator
{
public:
AmbientOcclusionCalculator(Volume<VoxelType>* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength);
~AmbientOcclusionCalculator();
void execute(void);
private:
Region m_region;
VolumeSampler<VoxelType> m_sampVolume;
Volume<VoxelType>* m_volInput;
Array<3, uint8_t>* m_arrayResult;
float m_fRayLength;
uint16_t mRandomUnitVectorIndex;
uint16_t mRandomVectorIndex;
uint16_t mIndexIncreament;
};
}
#include "AmbientOcclusionCalculator.inl"
#endif //__AmbientOcclusionCalculator_H__

View File

@ -0,0 +1,128 @@
/*******************************************************************************
Copyright (c) 2005-2009 David Williams
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*******************************************************************************/
#include "Array.h"
#include "Raycast.h"
#include "Volume.h"
#include "VolumeSampler.h"
#include "PolyVoxImpl/RandomUnitVectors.h"
#include "PolyVoxImpl/RandomVectors.h"
namespace PolyVox
{
template <typename VoxelType>
AmbientOcclusionCalculator<VoxelType>::AmbientOcclusionCalculator(Volume<VoxelType>* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength)
:m_region(region)
,m_sampVolume(volInput)
,m_volInput(volInput)
,m_arrayResult(arrayResult)
,m_fRayLength(fRayLength)
{
//Make sure that the size of the volume is an exact multiple of the size of the array.
assert(m_volInput.getWidth() % arrayResult.getDimension(0) == 0);
assert(m_volInput.getHeight() % arrayResult.getDimension(1) == 0);
assert(m_volInput.getDepth() % arrayResult.getDimension(2) == 0);
//Our initial indices. It doesn't matter exactly what we set here, but the code below makes
//sure they are different for different regions which helps reduce tiling patterns is the results.
mRandomUnitVectorIndex += m_region.getLowerCorner().getX() + m_region.getLowerCorner().getY() + m_region.getLowerCorner().getZ();
mRandomVectorIndex += m_region.getLowerCorner().getX() + m_region.getLowerCorner().getY() + m_region.getLowerCorner().getZ();
//This value helps us jump around in the array a bit more, so the
//nth 'random' value isn't always followed by the n+1th 'random' value.
mIndexIncreament = 1;
}
template <typename VoxelType>
AmbientOcclusionCalculator<VoxelType>::~AmbientOcclusionCalculator()
{
}
template <typename VoxelType>
void AmbientOcclusionCalculator<VoxelType>::execute(void)
{
const int iRatioX = m_volInput->getWidth() / m_arrayResult->getDimension(0);
const int iRatioY = m_volInput->getHeight() / m_arrayResult->getDimension(1);
const int iRatioZ = m_volInput->getDepth() / m_arrayResult->getDimension(2);
const int iRatioMax = std::max(std::max(iRatioX, iRatioY), iRatioZ);
const float fRatioX = iRatioX;
const float fRatioY = iRatioY;
const float fRatioZ = iRatioZ;
const float fRatioMax = iRatioMax;
const Vector3DFloat v3dRatio(fRatioX, fRatioY, fRatioZ);
const float fHalfRatioX = fRatioX * 0.5f;
const float fHalfRatioY = fRatioY * 0.5f;
const float fHalfRatioZ = fRatioZ * 0.5f;
const float fHalfRatioMax = fRatioMax * 0.5f;
const Vector3DFloat v3dHalfRatio(fHalfRatioX, fHalfRatioY, fHalfRatioZ);
const Vector3DFloat v3dOffset(0.5f,0.5f,0.5f);
RaycastResult raycastResult;
Raycast<VoxelType> raycast(m_volInput, Vector3DFloat(0.0f,0.0f,0.0f), Vector3DFloat(1.0f,1.0f,1.0f), raycastResult);
//This loop iterates over the bottom-lower-left voxel in each of the cells in the output array
for(uint16_t z = m_region.getLowerCorner().getZ(); z <= m_region.getUpperCorner().getZ(); z += iRatioZ)
{
for(uint16_t y = m_region.getLowerCorner().getY(); y <= m_region.getUpperCorner().getY(); y += iRatioY)
{
for(uint16_t x = m_region.getLowerCorner().getX(); x <= m_region.getUpperCorner().getX(); x += iRatioX)
{
//Compute a start position corresponding to
//the centre of the cell in the output array.
Vector3DFloat v3dStart(x, y, z);
v3dStart -= v3dOffset;
v3dStart += v3dHalfRatio;
//Keep track of how many rays did not hit anything
uint8_t uVisibleDirections = 0;
for(int ct = 0; ct < 255; ct++)
{
//We take a random vector with components going from -1 to 1 and scale it to go from -haflRatio to +halfRatio.
//This jitter value moves our sample point from the center of the array cell to somewhere else in the array cell
Vector3DFloat v3dJitter = randomVectors[(mRandomVectorIndex += (++mIndexIncreament)) % 1019]; //Prime number helps avoid repetition on sucessive loops.
v3dJitter *= v3dHalfRatio;
const Vector3DFloat v3dRayStart = v3dStart + v3dJitter;
Vector3DFloat v3dRayDirection = randomUnitVectors[(mRandomUnitVectorIndex += (++mIndexIncreament)) % 1021]; //Differenct prime number.
v3dRayDirection *= m_fRayLength;
raycast.setStart(v3dRayStart);
raycast.setDirection(v3dRayDirection);
raycast.execute();
if(raycastResult.foundIntersection == false)
{
++uVisibleDirections;
}
}
(*m_arrayResult)[z / iRatioZ][y / iRatioY][x / iRatioX] = uVisibleDirections;
}
}
}
}
}

View File

@ -0,0 +1,34 @@
/*******************************************************************************
Copyright (c) 2005-2009 David Williams
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*******************************************************************************/
#ifndef __PolyVox_RandomUnitVectors_H__
#define __PolyVox_RandomUnitVectors_H__
#include "Vector.h"
namespace PolyVox
{
extern POLYVOXCORE_API const Vector3DFloat randomUnitVectors[];
}
#endif //__PolyVox_RandomUnitVectors_H__

View File

@ -0,0 +1,34 @@
/*******************************************************************************
Copyright (c) 2005-2009 David Williams
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*******************************************************************************/
#ifndef __PolyVox_RandomVectors_H__
#define __PolyVox_RandomVectors_H__
#include "Vector.h"
namespace PolyVox
{
extern POLYVOXCORE_API const Vector3DFloat randomVectors[];
}
#endif //__PolyVox_RandomVectors_H__

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff