// EMERGENT GAME TECHNOLOGIES PROPRIETARY INFORMATION // // This software is supplied under the terms of a license agreement or // nondisclosure agreement with Emergent Game Technologies and may not // be copied or disclosed except in accordance with the terms of that // agreement. // // Copyright (c) 1996-2008 Emergent Game Technologies. // All Rights Reserved. // // Emergent Game Technologies, Chapel Hill, North Carolina 27517 // http://www.emergent.net //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- template inline NiTTerrainRandomAccessIterator:: NiTTerrainRandomAccessIterator() : m_pfBuffer(NULL), m_uiElementStride(0), m_uiTotalStride(0), m_bCompressionEnabled(false), m_bMorphingEnabled(false) { } //--------------------------------------------------------------------------- template <> inline NiTTerrainRandomAccessIterator::POSITION>:: NiTTerrainRandomAccessIterator(NiDataStreamLock* pkLock, NiUInt32 uiRegionIndex, const NiTerrainConfiguration& kConfiguration) { NiTStridedRandomAccessIterator kBaseIterator = pkLock->begin_region(uiRegionIndex); if (kBaseIterator.Exists()) m_pfBuffer = &kBaseIterator[0]; else m_pfBuffer = NULL; m_bCompressionEnabled = false; m_bMorphingEnabled = kConfiguration.IsMorphingDataEnabled(); m_uiElementStride = kConfiguration.GetNumPositionComponents(); m_uiTotalStride = pkLock->GetDataStream()->GetStride() / sizeof(float); } //--------------------------------------------------------------------------- template <> inline NiTTerrainRandomAccessIterator::NORMAL>:: NiTTerrainRandomAccessIterator(NiDataStreamLock* pkLock, NiUInt32 uiRegionIndex, const NiTerrainConfiguration& kConfiguration) { NiTStridedRandomAccessIterator kBaseIterator = pkLock->begin_region(uiRegionIndex); if (kBaseIterator.Exists()) m_pfBuffer = &kBaseIterator[0]; else m_pfBuffer = NULL; m_bCompressionEnabled = kConfiguration.IsLightingDataCompressionEnabled(); m_bMorphingEnabled = kConfiguration.IsMorphingDataEnabled(); m_uiElementStride = kConfiguration.GetNumNormalComponents(); m_uiTotalStride = pkLock->GetDataStream()->GetStride() / sizeof(float); } //--------------------------------------------------------------------------- template <> inline NiTTerrainRandomAccessIterator::TANGENT>:: NiTTerrainRandomAccessIterator(NiDataStreamLock* pkLock, NiUInt32 uiRegionIndex, const NiTerrainConfiguration& kConfiguration) { NiTStridedRandomAccessIterator kBaseIterator = pkLock->begin_region(uiRegionIndex); if (kBaseIterator.Exists()) m_pfBuffer = &kBaseIterator[0]; else m_pfBuffer = NULL; m_bCompressionEnabled = kConfiguration.IsLightingDataCompressionEnabled(); m_bMorphingEnabled = kConfiguration.IsMorphingDataEnabled(); m_uiElementStride = kConfiguration.GetNumTangentComponents(); m_uiTotalStride = pkLock->GetDataStream()->GetStride() / sizeof(float); } //--------------------------------------------------------------------------- template inline NiTTerrainRandomAccessIterator:: NiTTerrainRandomAccessIterator(NiDataStreamLock* pkLock, NiUInt32 uiRegionIndex, const NiTerrainConfiguration& kConfiguration) { NI_UNUSED_ARG(pkLock); NI_UNUSED_ARG(kConfiguration); NIASSERT(!"Invalid stream type"); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- template inline void NiTTerrainRandomAccessIterator:: Get(NiUInt32 uiIndex, NiPoint4& kPoint) const { NiUInt32 uiPos = uiIndex * GetTotalStride(); NIASSERT(GetElementStride() >= 4); kPoint.SetX(m_pfBuffer[uiPos]); kPoint.SetY(m_pfBuffer[++uiPos]); kPoint.SetZ(m_pfBuffer[++uiPos]); kPoint.SetW(m_pfBuffer[++uiPos]); } //--------------------------------------------------------------------------- template inline void NiTTerrainRandomAccessIterator:: Get(NiUInt32 uiIndex, NiPoint3& kPoint) const { NiUInt32 uiPos = uiIndex * GetTotalStride(); NIASSERT(GetElementStride() >= 3); kPoint.x = m_pfBuffer[uiPos]; kPoint.y = m_pfBuffer[++uiPos]; kPoint.z = m_pfBuffer[++uiPos]; } //--------------------------------------------------------------------------- template inline void NiTTerrainRandomAccessIterator:: Get(NiUInt32 uiIndex, NiPoint2& kPoint) const { NiUInt32 uiPos = uiIndex * GetTotalStride(); NIASSERT(GetElementStride() >= 2); kPoint.x = m_pfBuffer[uiPos]; kPoint.y = m_pfBuffer[++uiPos]; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- template inline float NiTTerrainRandomAccessIterator:: GetComponent(NiUInt32 uiIndex, COMPONENT eComponent) const { NIASSERT((NiUInt32)eComponent < GetElementStride()); return m_pfBuffer[uiIndex * GetTotalStride() + (NiUInt32)eComponent]; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- template inline void NiTTerrainRandomAccessIterator:: Set(NiUInt32 uiIndex, const NiPoint4& kPoint) const { NiUInt32 uiPos = uiIndex * GetTotalStride(); NIASSERT(GetElementStride() >= 4); m_pfBuffer[uiPos] = kPoint.X(); m_pfBuffer[++uiPos] = kPoint.Y(); m_pfBuffer[++uiPos] = kPoint.Z(); m_pfBuffer[++uiPos] = kPoint.W(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- template inline void NiTTerrainRandomAccessIterator:: Set(NiUInt32 uiIndex, const NiPoint3& kPoint) const { NiUInt32 uiPos = uiIndex * GetTotalStride(); NIASSERT(GetElementStride() >= 3); m_pfBuffer[uiPos] = kPoint.x; m_pfBuffer[++uiPos] = kPoint.y; m_pfBuffer[++uiPos] = kPoint.z; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- template inline void NiTTerrainRandomAccessIterator:: Set(NiUInt32 uiIndex, const NiPoint2& kPoint) const { NiUInt32 uiPos = uiIndex * GetTotalStride(); NIASSERT(GetElementStride() >= 2); m_pfBuffer[uiPos] = kPoint.x; m_pfBuffer[++uiPos] = kPoint.y; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- template inline void NiTTerrainRandomAccessIterator:: SetComponent(NiUInt32 uiIndex, COMPONENT eComponent, float fValue) const { NIASSERT(GetElementStride() >= (NiUInt32)eComponent); m_pfBuffer[uiIndex * GetTotalStride() + (NiUInt32)eComponent] = fValue; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- template <> inline void NiTTerrainRandomAccessIterator::POSITION>:: GetHighDetail(NiUInt32 uiIndex, NiPoint3& kPoint) const { NiUInt32 uiPos = uiIndex * GetTotalStride(); NIASSERT(GetElementStride() >= 3); kPoint.x = m_pfBuffer[uiPos]; kPoint.y = m_pfBuffer[++uiPos]; kPoint.z = m_pfBuffer[++uiPos]; } //--------------------------------------------------------------------------- template <> inline void NiTTerrainRandomAccessIterator::NORMAL>:: GetHighDetail(NiUInt32 uiIndex, NiPoint3& kPoint) const { NiUInt32 uiPos = uiIndex * GetTotalStride(); if (GetCompressionEnabled()) { NIASSERT(GetElementStride() >= 2); ((NiPoint4*)&m_pfBuffer[uiPos])->DecompressXYIntoNormalized( kPoint); } else { NIASSERT(GetElementStride() >= 3); kPoint.x = m_pfBuffer[uiPos]; kPoint.y = m_pfBuffer[++uiPos]; kPoint.z = m_pfBuffer[++uiPos]; } } //--------------------------------------------------------------------------- template <> inline void NiTTerrainRandomAccessIterator::TANGENT>:: GetHighDetail(NiUInt32 uiIndex, NiPoint3& kPoint) const { NiUInt32 uiPos = uiIndex * GetTotalStride(); if (GetCompressionEnabled()) { NIASSERT(GetElementStride() >= 2); kPoint.x = m_pfBuffer[uiPos]; kPoint.y = 0.0f; kPoint.z = m_pfBuffer[++uiPos]; } else { NIASSERT(GetElementStride() >= 3); kPoint.x = m_pfBuffer[uiPos]; kPoint.y = m_pfBuffer[++uiPos]; kPoint.z = m_pfBuffer[++uiPos]; } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- template <> inline void NiTTerrainRandomAccessIterator::POSITION>:: GetLowDetail(NiUInt32 uiIndex, NiPoint3& kPoint) const { if (!GetCompressionEnabled()) return; NiUInt32 uiPos = uiIndex * GetTotalStride(); NIASSERT(GetElementStride() >= 3); kPoint.x = m_pfBuffer[uiPos]; kPoint.y = m_pfBuffer[++uiPos]; kPoint.z = m_pfBuffer[uiPos + 2]; } //--------------------------------------------------------------------------- template <> inline void NiTTerrainRandomAccessIterator::NORMAL>:: GetLowDetail(NiUInt32 uiIndex, NiPoint3& kPoint) const { if (!GetCompressionEnabled()) return; NiUInt32 uiPos = uiIndex * GetTotalStride(); NIASSERT(GetElementStride() >= 4); ((NiPoint4*)&m_pfBuffer[uiPos])->DecompressZWIntoNormalized(kPoint); } //--------------------------------------------------------------------------- template <> inline void NiTTerrainRandomAccessIterator::TANGENT>:: GetLowDetail(NiUInt32 uiIndex, NiPoint3& kPoint) const { if (!GetCompressionEnabled()) return; NiUInt32 uiPos = uiIndex * GetTotalStride() + 2; NIASSERT(GetElementStride() >= 3); kPoint.x = m_pfBuffer[uiPos]; kPoint.y = 0.0f; kPoint.z = m_pfBuffer[++uiPos]; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- template <> inline void NiTTerrainRandomAccessIterator::NORMAL>:: GetHighDetail(NiUInt32 uiIndex, NiPoint2& kPoint) const { NiUInt32 uiPos = uiIndex * GetTotalStride(); if (GetCompressionEnabled()) { NIASSERT(GetElementStride() >= 2); kPoint.x = m_pfBuffer[uiPos]; kPoint.y = m_pfBuffer[++uiPos]; } else { NIASSERT(GetElementStride() >= 3); NiPoint4 kCompressed; kCompressed.CompressNormalizedIntoXY( *(NiPoint3*)&m_pfBuffer[uiPos]); kPoint.x = kCompressed.X(); kPoint.y = kCompressed.Y(); } } //--------------------------------------------------------------------------- template <> inline void NiTTerrainRandomAccessIterator::TANGENT>:: GetHighDetail(NiUInt32 uiIndex, NiPoint2& kPoint) const { NiUInt32 uiPos = uiIndex * GetTotalStride(); if (GetCompressionEnabled()) { NIASSERT(GetElementStride() >= 2); kPoint.x = m_pfBuffer[uiPos]; kPoint.y = m_pfBuffer[++uiPos]; } else { NIASSERT(GetElementStride() >= 3); kPoint.x = m_pfBuffer[uiPos]; kPoint.y = m_pfBuffer[uiPos + 2]; } } //--------------------------------------------------------------------------- template inline void NiTTerrainRandomAccessIterator:: GetHighDetail(NiUInt32 uiIndex, NiPoint2& kPoint) const { NI_UNUSED_ARG(uiIndex); NI_UNUSED_ARG(kPoint); NIASSERT(!"Invalid operation on this stream."); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- template <> inline void NiTTerrainRandomAccessIterator::NORMAL>:: GetLowDetail(NiUInt32 uiIndex, NiPoint2& kPoint) const { if (!GetCompressionEnabled()) return; NiUInt32 uiPos = uiIndex * GetTotalStride() + 2; NIASSERT(GetElementStride() >= 4); kPoint.x = m_pfBuffer[uiPos]; kPoint.y = m_pfBuffer[++uiPos]; } //--------------------------------------------------------------------------- template <> inline void NiTTerrainRandomAccessIterator::TANGENT>:: GetLowDetail(NiUInt32 uiIndex, NiPoint2& kPoint) const { if (!GetCompressionEnabled()) return; NiUInt32 uiPos = uiIndex * GetTotalStride() + 2; NIASSERT(GetElementStride() >= 4); kPoint.x = m_pfBuffer[uiPos]; kPoint.y = m_pfBuffer[++uiPos]; } //--------------------------------------------------------------------------- template inline void NiTTerrainRandomAccessIterator:: GetLowDetail(NiUInt32 uiIndex, NiPoint2& kPoint) const { NI_UNUSED_ARG(uiIndex); NI_UNUSED_ARG(kPoint); NIASSERT(!"Invalid operation on this stream."); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- template <> inline void NiTTerrainRandomAccessIterator::POSITION>:: SetHighDetail(NiUInt32 uiIndex, const NiPoint3& kPoint) const { NiUInt32 uiPos = uiIndex * GetTotalStride(); NIASSERT(GetElementStride() >= 3); m_pfBuffer[uiPos] = kPoint.x; m_pfBuffer[++uiPos] = kPoint.y; m_pfBuffer[++uiPos] = kPoint.z; } //--------------------------------------------------------------------------- template <> inline void NiTTerrainRandomAccessIterator::NORMAL>:: SetHighDetail(NiUInt32 uiIndex, const NiPoint3& kPoint) const { NiUInt32 uiPos = uiIndex * GetTotalStride(); if (GetCompressionEnabled()) { NIASSERT(GetElementStride() >= 2); ((NiPoint4*)&m_pfBuffer[uiPos])->CompressNormalizedIntoXY(kPoint); } else { NIASSERT(GetElementStride() >= 3); m_pfBuffer[uiPos] = kPoint.x; m_pfBuffer[++uiPos] = kPoint.y; m_pfBuffer[++uiPos] = kPoint.z; } } //--------------------------------------------------------------------------- template <> inline void NiTTerrainRandomAccessIterator::TANGENT>:: SetHighDetail(NiUInt32 uiIndex, const NiPoint3& kPoint) const { NiUInt32 uiPos = uiIndex * GetTotalStride(); if (GetCompressionEnabled()) { NIASSERT(GetElementStride() >= 2); m_pfBuffer[uiPos] = kPoint.x; m_pfBuffer[++uiPos] = kPoint.z; } else { NIASSERT(GetElementStride() >= 3); m_pfBuffer[uiPos] = kPoint.x; m_pfBuffer[++uiPos] = 0.0f; m_pfBuffer[++uiPos] = kPoint.z; } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- template <> inline void NiTTerrainRandomAccessIterator::POSITION>:: SetLowDetail(NiUInt32 uiIndex, const NiPoint3& kPoint) const { if (!GetMorphingEnabled()) return; NiUInt32 uiPos = uiIndex * GetTotalStride(); NIASSERT(GetElementStride() >= 4); m_pfBuffer[uiPos] = kPoint.x; m_pfBuffer[++uiPos] = kPoint.y; m_pfBuffer[uiPos + 2] = kPoint.z; } //--------------------------------------------------------------------------- template <> inline void NiTTerrainRandomAccessIterator::NORMAL>:: SetLowDetail(NiUInt32 uiIndex, const NiPoint3& kPoint) const { if (!GetMorphingEnabled()) return; NiUInt32 uiPos = uiIndex * GetTotalStride(); NIASSERT(GetElementStride() >= 4); ((NiPoint4*)&m_pfBuffer[uiPos])->CompressNormalizedIntoZW(kPoint); } //--------------------------------------------------------------------------- template <> inline void NiTTerrainRandomAccessIterator::TANGENT>:: SetLowDetail(NiUInt32 uiIndex, const NiPoint3& kPoint) const { if (!GetMorphingEnabled()) return; NiUInt32 uiPos = uiIndex * GetTotalStride() + 2; NIASSERT(GetElementStride() >= 4); m_pfBuffer[uiPos] = kPoint.x; m_pfBuffer[++uiPos] = kPoint.z; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- template <> inline void NiTTerrainRandomAccessIterator::POSITION>:: SetHighDetail(NiUInt32 uiIndex, const NiPoint2& kPoint) const { NI_UNUSED_ARG(uiIndex); NI_UNUSED_ARG(kPoint); NIASSERT(!"Invalid operation on Position stream."); } //--------------------------------------------------------------------------- template <> inline void NiTTerrainRandomAccessIterator::NORMAL>:: SetHighDetail(NiUInt32 uiIndex, const NiPoint2& kPoint) const { NiUInt32 uiPos = uiIndex * GetTotalStride(); NIASSERT(GetElementStride() >= 2); if (GetCompressionEnabled()) { m_pfBuffer[uiPos] = kPoint.x; m_pfBuffer[++uiPos] = kPoint.y; } else { NiPoint4 kCompressed; kCompressed.SetX(kPoint.x); kCompressed.SetY(kPoint.y); kCompressed.DecompressXYIntoNormalized( *(NiPoint3*)&m_pfBuffer[uiPos]); } } //--------------------------------------------------------------------------- template <> inline void NiTTerrainRandomAccessIterator::TANGENT>:: SetHighDetail(NiUInt32 uiIndex, const NiPoint2& kPoint) const { NiUInt32 uiPos = uiIndex * GetTotalStride(); NIASSERT(GetElementStride() >= 2); if (GetCompressionEnabled()) { m_pfBuffer[uiPos] = kPoint.x; m_pfBuffer[++uiPos] = kPoint.y; } else { m_pfBuffer[uiPos] = kPoint.x; m_pfBuffer[++uiPos] = 0.0f; m_pfBuffer[++uiPos] = kPoint.y; } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- template <> inline void NiTTerrainRandomAccessIterator::POSITION>:: SetLowDetail(NiUInt32 uiIndex, const NiPoint2& kPoint) const { NI_UNUSED_ARG(uiIndex); NI_UNUSED_ARG(kPoint); NIASSERT(!"Invalid operation on Position stream."); } //--------------------------------------------------------------------------- template <> inline void NiTTerrainRandomAccessIterator::NORMAL>:: SetLowDetail(NiUInt32 uiIndex, const NiPoint2& kPoint) const { if (!GetMorphingEnabled()) return; NiUInt32 uiPos = uiIndex * GetTotalStride() + 2; NIASSERT(GetElementStride() >= 4); m_pfBuffer[uiPos] = kPoint.x; m_pfBuffer[++uiPos] = kPoint.y; } //--------------------------------------------------------------------------- template <> inline void NiTTerrainRandomAccessIterator::TANGENT>:: SetLowDetail(NiUInt32 uiIndex, const NiPoint2& kPoint) const { if (!GetMorphingEnabled()) return; NiUInt32 uiPos = uiIndex * GetTotalStride() + 2; NIASSERT(GetElementStride() >= 4); m_pfBuffer[uiPos] = kPoint.x; m_pfBuffer[++uiPos] = kPoint.y; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- template inline NiUInt32 NiTTerrainRandomAccessIterator:: GetTotalStride() const { return m_uiTotalStride; } //--------------------------------------------------------------------------- template inline NiUInt32 NiTTerrainRandomAccessIterator:: GetElementStride() const { return m_uiElementStride; } //--------------------------------------------------------------------------- template inline bool NiTTerrainRandomAccessIterator:: GetMorphingEnabled() const { return m_bMorphingEnabled; } //--------------------------------------------------------------------------- template inline bool NiTTerrainRandomAccessIterator:: GetCompressionEnabled() const { return m_bCompressionEnabled; } //--------------------------------------------------------------------------- template inline bool NiTTerrainRandomAccessIterator:: Exists() const { return m_pfBuffer != NULL; } //--------------------------------------------------------------------------- template inline void NiTTerrainRandomAccessIterator:: CopyFrom(NiUInt32 uiDestIndex, const NiTTerrainRandomAccessIterator& kSource, NiUInt32 uiSourceIndex) const { NIASSERT(Exists() && kSource.Exists()); NiUInt32 uiDestOffset = GetTotalStride() * uiDestIndex; NiUInt32 uiSourceOffset = kSource.GetTotalStride() * uiSourceIndex; NiMemcpy(m_pfBuffer + uiDestOffset, kSource.m_pfBuffer + uiSourceOffset, GetElementStride()); } //---------------------------------------------------------------------------