/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. #ifndef CRYINCLUDE_TOOLS_PRT_PRTTYPES_H #define CRYINCLUDE_TOOLS_PRT_PRTTYPES_H #pragma once #pragma warning (disable : 4290) #pragma warning (disable : 4239) #pragma warning (disable : 4505) #pragma warning (disable : 4512) #undef min #undef max #include "SHAllocator.h" #include #include #include #include "SmartPtrAllocator.h" #include "SHMath.h" #include "Legendre.h" #include "ISHLog.h" //to be able to log everywhere extern NSH::ISHLog& GetSHLog(); class CSimpleIndexedMesh; class CSimpleIndexedObjMesh; namespace NSH { namespace NMaterial { struct ISHMaterial; } } //!< namespace containing all SH specific types and functions namespace NSH { //typedef std::basic_string, CSHAllocator > string; //!< NSH::string typedef to use internal allocator static const uint8 gs_cDefaultCoeffCount = 9; //!< default number of coefficients static const uint8 gs_cDefaultBandCount = 3; //!< default number of bands to use static const uint8 gs_cSupportedMaxBands = 5; //!< currently supported max band number static const uint32 gs_MaxSupportedCoefficientSize = 25; //!< maximal coefficients supported by matrix (bands*bands), determines which dimension to build for matrix typedef uint16 TSampleHandle; //!< sample handle type (suffice for at least 40000 samples) //since max is a somewhere declared macro, i cannot use numeric_limits const uint32 g_cMaxHandleTypeValue = ((2 << (sizeof(TSampleHandle) * 8 - 1)) - 1); //!< maximum value a handle type can get //!< descriptor for a spherical harmonics function, main values are the number of used bands and number of coefficients, but some other properties might be added typedef struct SDescriptor { uint8 Bands; //!< bands used uint8 Coefficients; //!< resulting number of coefficients //!< constructor just set it to some valid corresponding values SDescriptor(const uint8 cNumberOfBands = gs_cDefaultBandCount); const SDescriptor& operator=(const SDescriptor& rCopyFrom); }SDescriptor; /************************************************************************************************************************************************/ //simple compatible vector class for scalar built in types to make it work with different STLs, keep name similar to stl //be aware that it does not behave completely the same (no push_back, no reserve functionality) //has overhead of 4 bytes over array rather than 8 as std::vector template class prtvector { public: typedef prtvector TPRTVec; INSTALL_CLASS_NEW(TPRTVec) private: T *m_pElements; //the elements size_t m_ElemCount; //number of currently allocated elements public: typedef T* iterator; typedef const T* const_iterator; prtvector(); prtvector(const uint32 cInitialElemCount); prtvector(const prtvector& crCopyFrom); ~prtvector(); prtvector& operator=(const prtvector& crCopyFrom); void resize(const size_t cNewElemCount); void reserve(const size_t cNewElemCount); T& operator[](const size_t cIndex); const T& operator[](const size_t cIndex) const; const_iterator begin() const; iterator begin(); iterator end(); const_iterator end() const; const size_t size() const; const bool empty() const; }; /************************************************************************************************************************************************/ //simple double linked list class implementing push_back, iterator and remove //required to work with mixed STLs template class prtlist { public: typedef prtlist TPRTList; INSTALL_CLASS_NEW(TPRTList) private: template struct SListElem { typedef SListElem TPRTListElem; INSTALL_CLASS_NEW(TPRTListElem) TE elem; SListElem *pPrevious; SListElem *pNext; SListElem(); SListElem(const SListElem& crCopyFrom); SListElem(const TE& crElem); SListElem(SListElem *cpPrevious, SListElem *cpNext); TE& operator*(); const TE& operator*() const; TE& operator->(); const TE& operator->() const; SListElem& operator++(); SListElem operator++(int); SListElem& operator =(const SListElem& crElem); static SListElem CreateDummy(); const bool operator !=(const SListElem& crE) const; }; SListElem *m_pFirst; SListElem *m_pLastElem; SListElem m_LastDummy; public: typedef SListElem iterator; typedef const SListElem const_iterator; prtlist(); // const_iterator begin() const; iterator begin(); // const_iterator end() const; iterator end(); void remove(const T& crElem); void push_back(const T& crElem); }; /************************************************************************************************************************************************/ //!< scalar coefficient type template struct SScalarCoeff_tpl { typedef SScalarCoeff_tpl TScalarTypeTempl; INSTALL_CLASS_NEW(TScalarTypeTempl) SScalarCoeff_tpl(); SScalarCoeff_tpl(const TFloatType cX); const SScalarCoeff_tpl& operator=(const TFloatType cX); operator TFloatType&(); operator const TFloatType&()const; const TFloatType& operator[](const size_t cIndex)const; TFloatType& operator[](const size_t cIndex); template SScalarCoeff_tpl& operator=(const SScalarCoeff_tpl& crCopyFrom); static const uint8 Components(){return 1;} //!< needed for serialization typedef TFloatType TComponentType; TFloatType m_Value; //!< the encapsulated value }; typedef struct SScalarCoeff_tpl TScalarCoeff; /************************************************************************************************************************************************/ //!< rgb coefficient type template struct SRGBCoeff_tpl : public Vec3_tpl { typedef SRGBCoeff_tpl TRGBTypeTempl; INSTALL_CLASS_NEW(TRGBTypeTempl) SRGBCoeff_tpl(); SRGBCoeff_tpl(const TFloatType cX, const TFloatType cY, const TFloatType cZ); SRGBCoeff_tpl(const Vec3_tpl& rCopyFrom); const SRGBCoeff_tpl& operator *=(const SRGBCoeff_tpl& rSource); const SRGBCoeff_tpl& operator *=(const TFloatType cScalar); template const SRGBCoeff_tpl& operator =(const Vec3_tpl& rCopyFrom); template operator SRGBCoeff_tpl()const; static const uint8 Components(){return 3;} //!< needed for serialization typedef TFloatType TComponentType; }; typedef struct SRGBCoeff_tpl TRGBCoeffD; typedef struct SRGBCoeff_tpl TRGBCoeffF; template const SRGBCoeff_tpl operator *(const SRGBCoeff_tpl& r0, const SRGBCoeff_tpl& r1); template const SRGBCoeff_tpl operator +(const SRGBCoeff_tpl& r0, const SRGBCoeff_tpl& r1); template const SRGBCoeff_tpl operator *(const SRGBCoeff_tpl& r0, const TFloatType cScalar); /************************************************************************************************************************************************/ //!< polar coordinate set //!< theta is in the range [0...g_cPi] (altitude) //!< phi is in the range [0...2 g_cPi] (azimuth) template struct SPolarCoord_tpl { TFloatType theta; //!< theta angle TFloatType phi; //!< phi angle SPolarCoord_tpl(); SPolarCoord_tpl(const TFloatType cTheta, const TFloatType cPhi); template operator SPolarCoord_tpl()const; }; typedef SPolarCoord_tpl TPolarCoord; /************************************************************************************************************************************************/ //!< cartesian coordinate set template struct SCartesianCoord_tpl : public Vec3_tpl { SCartesianCoord_tpl(); SCartesianCoord_tpl(const TFloatType cX, const TFloatType cY, const TFloatType cZ); template SCartesianCoord_tpl(const SCartesianCoord_tpl& rcCopyFrom); const SCartesianCoord_tpl operator-()const; template const SCartesianCoord_tpl& operator =(const Vec3_tpl& rcAssignFrom); template operator SCartesianCoord_tpl()const; }; typedef SCartesianCoord_tpl TCartesianCoord; //!< converts a polar coordinate into a cartesian //!< 0,0,1 means origin with z pointing upwards //!< NOTE: output is in SH coordinate system, engine and max negates x and y template void ConvertToCartesian(SCartesianCoord_tpl& rCartesian, const SPolarCoord_tpl& crPolar); //!< converts a unit sphere cartesian coordinate into a polar //!< theta is mapped into the range [0...g_cPi] (altitude) //!< phi is into the range [0...2 g_cPi] (azimuth) //!< NOTE: input is suppose to be in SH coordinate system, engine and max negates x and y template void ConvertUnitToPolar(SPolarCoord_tpl& rPolar, const SCartesianCoord_tpl& crCartesian); //!< converts a common sphere cartesian coordinate into a polar //!< theta is mapped into the range [0...g_cPi] (altitude) //!< phi is into the range [0...2 g_cPi] (azimuth) //!< NOTE: input is suppose to be in SH coordinate system, engine and max negates x and y template void ConvertToPolar(SPolarCoord_tpl& rPolar, const SCartesianCoord_tpl& crCartesian); /************************************************************************************************************************************************/ //!< calculates the rotation matrix around (0,0,0) to rotate from rFrom to (0,0,1) template void CalcRotMatrixToSphereOrigin(Matrix33_tpl& rRotMatrix, const TCartesianCoord& rFrom); template void CalcRotMatrixToSphereOrigin(Matrix33_tpl& rRotMatrix, const TPolarCoord& rFrom); //!< calculates the rotation matrix around (0,0,0) to rotate from (0,0,1) to rTo template void CalcRotMatrixFromSphereOrigin(Matrix33_tpl& rRotMatrix, const TCartesianCoord& rTo); template void CalcRotMatrixFromSphereOrigin(Matrix33_tpl& rRotMatrix, const TPolarCoord& rTo); /************************************************************************************************************************************************/ typedef enum ECoeffChoice {ALL_COEFFS, NO_COEFF_Y2m2, NO_COEFF_Y22} ECoeffChoice; //!< enum describing coeff choice used for SH-lookup /************************************************************************************************************************************************/ template class CSample_tpl; //!< list of (scalar/RGB) coefficients template< typename CoeffType > struct SCoeffList_tpl { typedef CoeffType TComponentType; typedef typename CoeffType::TComponentType TComponentFloatType; explicit SCoeffList_tpl(const SDescriptor& crDescriptor); explicit SCoeffList_tpl(const uint32 cCoefficients = gs_cDefaultCoeffCount); template< typename CoeffTypeFrom > SCoeffList_tpl(const SCoeffList_tpl& rCopyFrom); template< typename CoeffTypeFrom > SCoeffList_tpl& operator=(const SCoeffList_tpl& rCopyFrom); void ResetToZero(); void ReSize(const SDescriptor& crDescriptor); CoeffType& operator () (const int32 cL, const int32 cM); //!< access operators for a particular band index const CoeffType& operator () (const int32 cL, const int32 cM) const; const SCoeffList_tpl& operator +=(const SCoeffList_tpl& rToAdd); const SCoeffList_tpl& operator *=(const double cScalar); const CoeffType* const GetCoeffs() const; const CoeffType PerformLookup(const CSample_tpl >& crSample, const ECoeffChoice cCoeffChoice = ALL_COEFFS) const; const size_t size()const; //!< access operator to make it act like a vector CoeffType& operator [](const size_t cIndex); const CoeffType operator [](const size_t cIndex)const; // std::vector > m_Coeffs; //!< coefficients set corresponding to the bands prtvector m_Coeffs; //!< coefficients set corresponding to the bands ~SCoeffList_tpl(); }; template const SCoeffList_tpl operator +(const SCoeffList_tpl& r0, const SCoeffList_tpl& r1); template const SCoeffList_tpl operator *(const SCoeffList_tpl& r0, const SCoeffList_tpl& r1); template const SCoeffList_tpl operator *(const SCoeffList_tpl& r0, const double cScalar); /************************************************************************************************************************************************/ //!< sample on sphere containing all required data for one coefficient set and the set itself template class CSample_tpl { public: typedef CoeffTypeList TComponentType; //!< constructor for one sample on a sphere CSample_tpl(const SDescriptor& crDescriptor, const TPolarCoord& crPolarCoord, const TSampleHandle cHandle = 0); CSample_tpl(); CSample_tpl(const CSample_tpl& crCopyFrom); //!< copy ctor, sets handle to 0 (be careful using it) void Validate()const; const uint8 NumberOfCoeffs()const; //!< retrieves the number of coefficients const TCartesianCoord& GetCartesianPos()const; //!< retrieves the cartesian position on sphere const TPolarCoord& GetPolarPos()const; //!< retrieves the polar position on sphere const CoeffTypeList& Coeffs()const; //!< retrieves the coefficients list CoeffTypeList& Coeffs(); //!< retrieves the coefficients list void SetHandle(const TSampleHandle cHandle); //!< sets a new Handle const TSampleHandle GetHandle()const; //!< sets a new Handle protected: #if defined(_DEBUG) bool m_Constructed; #endif TCartesianCoord m_CartCoord; //!< cartesian coordinate TPolarCoord m_PolarCoord; //!< corresponding polar coordinate CoeffTypeList m_Coeffs; //!< coefficients for this sample, depending on descriptor TSampleHandle m_Handle; //!< for indexing and identifying the samples }; typedef CSample_tpl > TSample;//!< scalar sample type /************************************************************************************************************************************************/ //!< return value for ray caster telling which triangle is the closest one intersecting ray struct SRayResult { const CSimpleIndexedMesh* pMesh; //!< mesh triangle belongs to int32 faceID; //!< triangle face id within pMesh Vec3 baryCoord; //!< barycentric coordinate of hit SRayResult() : pMesh(NULL), faceID(-1), baryCoord(0.f,0.f,0.f){} }; /************************************************************************************************************************************************/ typedef std::pair TUint32Pair; typedef std::pair TFloatPair; typedef std::vector > TGeomVec; typedef std::vector >, CSHAllocator > > > TSampleVec; //!< sample vector for primitive SH samples typedef struct SRGBCoeff_tpl TRGBCoeffType;//typedef it to the same as the scalar coefficients are typedef std::set, CSHAllocator > TVertexIndexSet; //used for recording vertex indices typedef std::vector > TUint32Vec; typedef std::vector > TVec3Vec; typedef std::vector, CSHAllocator > > TRGBCoeffVec; typedef std::vector > TRGBCoeffVecVec; typedef prtvector > TScalarCoeffVec; typedef prtvector TScalarCoeffVecVec; typedef prtvector TFloatPairVec;//used outside typedef prtvector TFloatPairVecVec; typedef std::vector > TBoolVec; typedef std::vector > TVecDVec; typedef std::vector > TFloatPtrVec; typedef std::vector > TRayResultVec; //!< describes the compression for each material(set of decompression values and so on) struct SCompressionInfo { TFloatPairVec compressionValue; //!< compression scale values and center offset for direct coeffs, individual for each mesh and material bool isCompressed; //!< indicates the compression SCompressionInfo() : isCompressed(false), compressionValue((const uint32)0){} }; typedef prtvector TCompressionInfo; } #include "PRTTypes.inl" #endif // CRYINCLUDE_TOOLS_PRT_PRTTYPES_H