254 lines
7.4 KiB
C++
254 lines
7.4 KiB
C++
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
|
// Copyright (C) 2010 Winch Gate Property Limited
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as
|
|
// published by the Free Software Foundation, either version 3 of the
|
|
// License, or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#ifndef NL_PS_UTIL_H
|
|
#define NL_PS_UTIL_H
|
|
|
|
#include "nel/misc/types_nl.h"
|
|
#include "nel/misc/aabbox.h"
|
|
#include "nel/misc/vector.h"
|
|
#include "nel/misc/rgba.h"
|
|
|
|
|
|
|
|
namespace NLMISC
|
|
{
|
|
class CMatrix;
|
|
class CVector;
|
|
};
|
|
|
|
namespace NL3D
|
|
{
|
|
|
|
|
|
class CFontGenerator;
|
|
class CFontManager;
|
|
class IDriver;
|
|
|
|
|
|
/**
|
|
* This struct contains utility functions used by the particle system.
|
|
* \author Nicolas Vizerie
|
|
* \author Nevrax France
|
|
* \date 2001
|
|
*/
|
|
struct CPSUtil
|
|
{
|
|
public:
|
|
/// Register the classes of the system. Must be called when serializing.
|
|
static void registerSerialParticleSystem(void);
|
|
|
|
/// Draw a bounding box.
|
|
static void displayBBox(NL3D::IDriver *driver, const NLMISC::CAABBox &box, NLMISC::CRGBA col = NLMISC::CRGBA::White);
|
|
|
|
/// Draw a sphere
|
|
static void displaySphere(NL3D::IDriver &driver, float radius, const NLMISC::CVector ¢er, uint nbSubdiv = 4, NLMISC::CRGBA color = NLMISC::CRGBA::White);
|
|
|
|
|
|
/** Draw a disc (not filled)
|
|
* \param mat : a matrix, whose K vector is normal to the plane containing the disc
|
|
*/
|
|
static void displayDisc(NL3D::IDriver &driver, float radius, const NLMISC::CVector ¢er, const NLMISC::CMatrix &mat, uint nbSubdiv = 32, NLMISC::CRGBA color = NLMISC::CRGBA::White);
|
|
|
|
|
|
/** draw a cylinder (not filled)
|
|
* \param dim dimension of the cylinder along each axis, packed in a vector
|
|
*/
|
|
static void displayCylinder(NL3D::IDriver &driver, const NLMISC::CVector ¢er, const NLMISC::CMatrix &mat, const NLMISC::CVector &dim, uint nbSubdiv = 32, NLMISC::CRGBA color = NLMISC::CRGBA::White);
|
|
|
|
/// display a 3d quad in wireline, by using the 4 gicen corners
|
|
static void display3DQuad(NL3D::IDriver &driver, const NLMISC::CVector &c1, const NLMISC::CVector &c2
|
|
,const NLMISC::CVector &c3, const NLMISC::CVector &c4, NLMISC::CRGBA color = NLMISC::CRGBA::White);
|
|
|
|
|
|
/// enlarge a bounding box by the specified radius
|
|
inline static void addRadiusToAABBox(NLMISC::CAABBox &box, float radius);
|
|
|
|
/// display a basis using the given matrix. The model matrix must be restored after this call
|
|
static void displayBasis(NL3D::IDriver *driver, const NLMISC::CMatrix &modelMat, const NLMISC::CMatrix &m, float size, CFontGenerator &fg, CFontManager &fm);
|
|
|
|
|
|
/** display an arrow (the same that is used with displayBasis)
|
|
* The user must setup the model matrix himself
|
|
* \param driver the driver used for rendering
|
|
* \param start start point of the arrow
|
|
* \param v direction of the arrow
|
|
* \param size size of the arrow (will be drawn as size * v)
|
|
* \param col1 color of the arrow start
|
|
* \param col2 color of the arrow end
|
|
*/
|
|
|
|
static void displayArrow(NL3D::IDriver *driver, const NLMISC::CVector &start, const NLMISC::CVector &v, float size, NLMISC::CRGBA col1, NLMISC::CRGBA col2);
|
|
|
|
/// display a string at the given world position. The model matrix must be restored after this call
|
|
|
|
static void print(NL3D::IDriver *driver, const std::string &text, CFontGenerator &fg, CFontManager &fm, const NLMISC::CVector &pos, float size, NLMISC::CRGBA col = NLMISC::CRGBA::White);
|
|
|
|
|
|
/** build a basis from a vector using Schmidt orthogonalization method
|
|
* \param v K axis in the resulting basis
|
|
* \param dest The matrix containing the result. Only the rotation part is modified
|
|
*/
|
|
static void buildSchmidtBasis(const NLMISC::CVector &v, NLMISC::CMatrix &dest);
|
|
|
|
|
|
/** get a cosine from the fast cosine table (which must be have initialised with initFastCosNSinTable).
|
|
* 256 <=> 2 Pi
|
|
*/
|
|
static inline float getCos(sint32 angle)
|
|
{
|
|
nlassert(_CosTableInitialized == true);
|
|
return _CosTable[angle & 0xff];
|
|
}
|
|
|
|
/** get a cosine from the fast cosine table (which must be have initialised with initFastCosNSinTable).
|
|
* 256 <=> 2 Pi
|
|
*/
|
|
static inline float getSin(sint32 angle)
|
|
{
|
|
nlassert(_CosTableInitialized == true);
|
|
return _SinTable[angle & 0xff];
|
|
}
|
|
|
|
/** Init the table for cosine and sinus lookup
|
|
* \see getCos(), getSin()
|
|
*/
|
|
static void initFastCosNSinTable(void);
|
|
|
|
|
|
/** compute a perlin noise value, that will range from [0 to 1]
|
|
* The first octave has the unit size
|
|
* \see initPerlinNoiseTable()
|
|
*/
|
|
static inline float buildPerlinNoise(NLMISC::CVector &pos, uint nbOctaves);
|
|
|
|
/** init the table used by perlin noise.
|
|
* This must be used before any call to buildPerlinNoise
|
|
*/
|
|
static void initPerlinNoiseTable(void);
|
|
|
|
|
|
private:
|
|
static void registerForces();
|
|
static void registerParticles();
|
|
static void registerEmitters();
|
|
static void registerZones();
|
|
static void registerAttribs();
|
|
|
|
static bool _CosTableInitialized;
|
|
static bool _PerlinNoiseTableInitialized;
|
|
// a table for fast cosine lookup
|
|
static float _CosTable[256];
|
|
// a table for fast sinus lookup
|
|
static float _SinTable[256];
|
|
static float _PerlinNoiseTab[1024];
|
|
// used by perlin noise to compute each octave
|
|
static float getInterpolatedNoise(const NLMISC::CVector &pos);
|
|
// get non interpolated noise
|
|
static float getPerlinNoise(uint x, uint y, uint z);
|
|
};
|
|
|
|
///////////////////////////
|
|
// inline implementation //
|
|
///////////////////////////
|
|
|
|
inline void CPSUtil::addRadiusToAABBox(NLMISC::CAABBox &box, float radius)
|
|
{
|
|
box.setHalfSize(box.getHalfSize() + NLMISC::CVector(radius, radius, radius) );
|
|
}
|
|
|
|
|
|
// get non interpolated noise
|
|
inline float CPSUtil::getPerlinNoise(uint x, uint y, uint z)
|
|
{
|
|
return _PerlinNoiseTab[(x ^ y ^ z) & 1023];
|
|
}
|
|
|
|
|
|
inline float CPSUtil::getInterpolatedNoise(const NLMISC::CVector &pos)
|
|
{
|
|
uint x = (uint) pos.x
|
|
, y = (uint) pos.y
|
|
, z = (uint) pos.z;
|
|
|
|
// we want to avoid costly ctor call there...
|
|
float fx = pos.x - x
|
|
, fy = pos.y - y
|
|
, fz = pos.z - z;
|
|
|
|
// we use the following topology to get the value :
|
|
//
|
|
//
|
|
// z
|
|
// | 7-----6
|
|
// / /
|
|
// 4-----5 |
|
|
// | | |
|
|
// | 3 | |2
|
|
// | | /
|
|
// 0_____1/__x
|
|
|
|
|
|
const float v0 = getPerlinNoise(x, y, z)
|
|
,v1 = getPerlinNoise(x + 1, y, z)
|
|
,v2 = getPerlinNoise(x + 1, y + 1, z)
|
|
,v3 = getPerlinNoise(x, y + 1, z)
|
|
,v4 = getPerlinNoise(x, y, z + 1)
|
|
,v5 = getPerlinNoise(x + 1, y, z + 1)
|
|
,v6 = getPerlinNoise(x + 1, y + 1, z + 1)
|
|
,v7 = getPerlinNoise(x, y + 1, z + 1);
|
|
|
|
|
|
const float h1 = fx * v1 + (1.f - fx) * v0
|
|
,h2 = fx * v3 + (1.f - fx) * v2
|
|
,h3 = fx * v5 + (1.f - fx) * v4
|
|
,h4 = fx * v7 + (1.f - fx )* v6;
|
|
|
|
const float c1 = fy * h2 + (1.f - fy) * h1
|
|
,c2 = fy * h4 + (1.f - fy) * h3;
|
|
|
|
return fz * c2 + (1.f - fz) * c1;
|
|
}
|
|
|
|
|
|
inline float CPSUtil::buildPerlinNoise(NLMISC::CVector &pos, uint numOctaves)
|
|
{
|
|
nlassert(_PerlinNoiseTableInitialized);
|
|
|
|
float result = 0;
|
|
float fact = .5f;
|
|
float scale = 1.f;
|
|
|
|
for (uint k = 0; k < numOctaves; k++)
|
|
{
|
|
result += fact * getInterpolatedNoise(scale * pos);
|
|
fact *= .5f;
|
|
scale *= 1.2537f;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} // NL3D
|
|
|
|
|
|
#endif // NL_PS_UTIL_H
|
|
|
|
/* End of ps_util.h */
|