Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 namespace PolyVox
00025 {
00026 template< template<typename> class VolumeType, typename VoxelType>
00027 AmbientOcclusionCalculator<VolumeType, VoxelType>::AmbientOcclusionCalculator(VolumeType<VoxelType>* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement)
00028 :m_region(region)
00029 ,m_sampVolume(volInput)
00030 ,m_volInput(volInput)
00031 ,m_arrayResult(arrayResult)
00032 ,m_fRayLength(fRayLength)
00033 ,m_uNoOfSamplesPerOutputElement(uNoOfSamplesPerOutputElement)
00034 ,mRandomUnitVectorIndex(0)
00035 ,mRandomVectorIndex(0)
00036 {
00037
00038 assert(m_volInput->getWidth() % arrayResult->getDimension(0) == 0);
00039 assert(m_volInput->getHeight() % arrayResult->getDimension(1) == 0);
00040 assert(m_volInput->getDepth() % arrayResult->getDimension(2) == 0);
00041
00042
00043
00044 mRandomUnitVectorIndex += m_region.getLowerCorner().getX() + m_region.getLowerCorner().getY() + m_region.getLowerCorner().getZ();
00045 mRandomVectorIndex += m_region.getLowerCorner().getX() + m_region.getLowerCorner().getY() + m_region.getLowerCorner().getZ();
00046
00047
00048
00049 mIndexIncreament = 1;
00050 }
00051
00052 template< template<typename> class VolumeType, typename VoxelType>
00053 AmbientOcclusionCalculator<VolumeType, VoxelType>::~AmbientOcclusionCalculator()
00054 {
00055 }
00056
00057 template< template<typename> class VolumeType, typename VoxelType>
00058 void AmbientOcclusionCalculator<VolumeType, VoxelType>::execute(void)
00059 {
00060 const int iRatioX = m_volInput->getWidth() / m_arrayResult->getDimension(0);
00061 const int iRatioY = m_volInput->getHeight() / m_arrayResult->getDimension(1);
00062 const int iRatioZ = m_volInput->getDepth() / m_arrayResult->getDimension(2);
00063
00064 const float fRatioX = iRatioX;
00065 const float fRatioY = iRatioY;
00066 const float fRatioZ = iRatioZ;
00067 const Vector3DFloat v3dRatio(fRatioX, fRatioY, fRatioZ);
00068
00069 const float fHalfRatioX = fRatioX * 0.5f;
00070 const float fHalfRatioY = fRatioY * 0.5f;
00071 const float fHalfRatioZ = fRatioZ * 0.5f;
00072 const Vector3DFloat v3dHalfRatio(fHalfRatioX, fHalfRatioY, fHalfRatioZ);
00073
00074 const Vector3DFloat v3dOffset(0.5f,0.5f,0.5f);
00075
00076 RaycastResult raycastResult;
00077 Raycast<VolumeType, VoxelType> raycast(m_volInput, Vector3DFloat(0.0f,0.0f,0.0f), Vector3DFloat(1.0f,1.0f,1.0f), raycastResult);
00078
00079
00080 for(uint16_t z = m_region.getLowerCorner().getZ(); z <= m_region.getUpperCorner().getZ(); z += iRatioZ)
00081 {
00082 for(uint16_t y = m_region.getLowerCorner().getY(); y <= m_region.getUpperCorner().getY(); y += iRatioY)
00083 {
00084 for(uint16_t x = m_region.getLowerCorner().getX(); x <= m_region.getUpperCorner().getX(); x += iRatioX)
00085 {
00086
00087
00088 Vector3DFloat v3dStart(x, y, z);
00089 v3dStart -= v3dOffset;
00090 v3dStart += v3dHalfRatio;
00091
00092
00093 uint8_t uVisibleDirections = 0;
00094
00095 for(int ct = 0; ct < m_uNoOfSamplesPerOutputElement; ct++)
00096 {
00097
00098
00099 Vector3DFloat v3dJitter = randomVectors[(mRandomVectorIndex += (++mIndexIncreament)) % 1019];
00100 v3dJitter *= v3dHalfRatio;
00101 const Vector3DFloat v3dRayStart = v3dStart + v3dJitter;
00102
00103 Vector3DFloat v3dRayDirection = randomUnitVectors[(mRandomUnitVectorIndex += (++mIndexIncreament)) % 1021];
00104 v3dRayDirection *= m_fRayLength;
00105
00106 raycast.setStart(v3dRayStart);
00107 raycast.setDirection(v3dRayDirection);
00108 raycast.execute();
00109
00110 if(raycastResult.foundIntersection == false)
00111 {
00112 ++uVisibleDirections;
00113 }
00114 }
00115
00116 float fVisibility;
00117 if(m_uNoOfSamplesPerOutputElement == 0)
00118 {
00119
00120
00121 fVisibility = 1.0f;
00122 }
00123 else
00124 {
00125 fVisibility = static_cast<float>(uVisibleDirections) / static_cast<float>(m_uNoOfSamplesPerOutputElement);
00126 assert((fVisibility >= 0.0f) && (fVisibility <= 1.0f));
00127 }
00128
00129 (*m_arrayResult)[z / iRatioZ][y / iRatioY][x / iRatioX] = static_cast<uint8_t>(255.0f * fVisibility);
00130 }
00131 }
00132 }
00133 }
00134 }