ploygonal-shaped grid

kARUN4

19-05-2010 19:58:00

how can i make water in a polygonal shaped surface or maybe assign hydrax to a custom mesh?

it is a picture of a dam witch must collect water in the back of it.

kARUN4

24-05-2010 06:42:11

Done!
I can tell you how , if you like

Fruz

25-05-2010 08:28:41

It would really help me if you could say me how you've done this :).

Indeed I'm trying to use Hydrax on a custom Mesh, wich have a HardwareVertexBufferSharedPtr and a HardwareIndexBufferSharedPtr.
I think I have to create a new Module, so I began with that, but I'm not really sure of what I have to do inside, do I have to replace the IndexBuffer and VertexBuffer of the Hydrax Mesh with my ones, in my own Mesh ?

Thanks.

kARUN4

26-05-2010 12:15:20

To the forum Admin : is it allowed to paste all the module here?

Xavyiy

28-05-2010 11:54:59

Of course you can ;)

kARUN4

29-05-2010 07:44:43

As you can see this is a manipulated copy of simplegrid.h and cpp
custom grid is a square shaped grid with one sine curved side. the constructor gets a displacement witch is the maximum displacement in the middle of that side. you can sstomize it by changing the sine formula in the cpp file.
//----------------------------------------------CustomGrid.h---------------------------------------

#ifndef _Hydrax_Modules_CustomGrid_H_
#define _Hydrax_Modules_CustomGrid_H_

#include "../../Prerequisites.h"

#include "../../Hydrax.h"
#include "../../Mesh.h"
#include "../Module.h"

namespace Hydrax{ namespace Module
{
/** Hydrax simple grid module
*/
class DllExport CustomGrid : public Module
{
public:
/** Struct wich contains Hydrax simple grid module options
*/
struct Options
{
/// Projected grid complexity (N*N)
int Complexity;
/// Size
Size MeshSize;
/// Strength
float Strength;
/// Smooth
bool Smooth;
/// Choppy waves
bool ChoppyWaves;
/// Choppy waves strength
float ChoppyStrength;

int Displacement;
/** Default constructor
*/
Options()
: Complexity(256)
, MeshSize(Size(100))
, Strength(32.5f)
, Smooth(false)
, ChoppyWaves(true)
, ChoppyStrength(0.065f)
, Displacement(0)
{
}

/** Constructor
@param _Complexity Projected grid complexity
@param _MeshSize Water mesh size
*/
Options(const int &_Complexity,
const Size &_MeshSize,const int &_Displacement)
: Complexity(_Complexity)
, MeshSize(_MeshSize)
, Strength(32.5f)
, Smooth(false)
, ChoppyWaves(true)
, ChoppyStrength(0.065f)
, Displacement(_Displacement)
{
}

/** Constructor
@param _Complexity Projected grid complexity
@param _MeshSize Water mesh size
@param _Strength Perlin noise strength
@param _Smooth Smooth vertex?
@param _ChoppyWaves Choppy waves enabled? Note: Only with Materialmanager::NM_VERTEX normal mode.
@param _ChoppyStrength Choppy waves strength Note: Only with Materialmanager::NM_VERTEX normal mode.
*/
Options(const int &_Complexity,
const Size &_MeshSize,
const float &_Strength,
const bool &_Smooth,
const bool &_ChoppyWaves,
const float &_ChoppyStrength)
: Complexity(_Complexity)
, MeshSize(_MeshSize)
, Strength(_Strength)
, Smooth(_Smooth)
, ChoppyWaves(_ChoppyWaves)
, ChoppyStrength(_ChoppyStrength)
{
}
};

/** Constructor
@param h Hydrax manager pointer
@param n Hydrax noise module
@param NormalMode Switch between MaterialManager::NM_VERTEX and Materialmanager::NM_RTT
*/
CustomGrid(Hydrax *h, int,Noise::Noise *n, const MaterialManager::NormalMode& NormalMode);

/** Constructor
@param h Hydrax manager pointer
@param n Hydrax noise module
@param NormalMode Switch between MaterialManager::NM_VERTEX and Materialmanager::NM_RTT
@param Options Perlin options
*/
CustomGrid(Hydrax *h, int,Noise::Noise *n, const MaterialManager::NormalMode& NormalMode, const Options &Options);

/** Destructor
*/
~CustomGrid();

/** Create
*/
void create();

/** Remove
*/
void remove();

/** Call it each frame
@param timeSinceLastFrame Time since last frame(delta)
*/
void update(const Ogre::Real &timeSinceLastFrame);

/** Set options
@param Options Options
*/
void setOptions(const Options &Options);

/** Save config
@param Data String reference
*/
void saveCfg(Ogre::String &Data);

/** Load config
@param CgfFile Ogre::ConfigFile reference
@return True if is the correct module config
*/
bool loadCfg(Ogre::ConfigFile &CfgFile);

/** Get the current heigth at a especified world-space point
@param Position X/Z World position
@return Heigth at the given position in y-World coordinates, if it's outside of the water return -1
*/
float getHeigth(const Ogre::Vector2 &Position);

/** Get current options
@return Current options
*/
inline const Options& getOptions() const
{
return mOptions;
}

inline Mesh::POS_NORM_VERTEX* getVertices() const
{
return static_cast<Mesh::POS_NORM_VERTEX*>(mVertices);
}

private:
/** Calcule current normals
*/
void _calculeNormals();

/** Perform choppy waves
*/
void _performChoppyWaves();
/// Vertex pointer (Mesh::POS_NORM_VERTEX or Mesh::POS_VERTEX)
void *mVertices;

/// Use it to store vertex positions when choppy displacement is enabled
Mesh::POS_NORM_VERTEX* mVerticesChoppyBuffer;

/// Our projected grid options
Options mOptions;

/// Our Hydrax pointer
Hydrax* mHydrax;

Ogre::Real mDisplacement;
};
}}

#endif

//----------------------------------------------CustomGrid.cpp---------------------------------------

#include "CustomGrid.h"

namespace Hydrax{
namespace Module
{

Mesh::VertexType _MG_getVertexTypeFromNormalMode(const MaterialManager::NormalMode& NormalMode)
{
if (NormalMode == MaterialManager::NM_VERTEX)
{
return Mesh::VT_POS_NORM;
}

// NM_RTT
return Mesh::VT_POS;
}

Ogre::String _MG_getNormalModeString(const MaterialManager::NormalMode& NormalMode)
{
if (NormalMode == MaterialManager::NM_VERTEX)
{
return "Vertex";
}

return "Rtt";
}

CustomGrid::CustomGrid(Hydrax *h, int Displacement, Noise::Noise *n, const MaterialManager::NormalMode& NormalMode)
: Module("CustomGrid" + _MG_getNormalModeString(NormalMode),
n, Mesh::Options(256, Size(100), _MG_getVertexTypeFromNormalMode(NormalMode)), NormalMode)
, mHydrax(h)
, mVertices(0)
, mVerticesChoppyBuffer(0)
,mDisplacement(Displacement)
{
}

CustomGrid::CustomGrid(Hydrax *h, int Displacement, Noise::Noise *n, const MaterialManager::NormalMode& NormalMode, const Options &Options)
: Module("CustomGrid" + _MG_getNormalModeString(NormalMode),
n, Mesh::Options(Options.Complexity, Size(Options.MeshSize), _MG_getVertexTypeFromNormalMode(NormalMode)), NormalMode)
, mHydrax(h)
, mVertices(0)
, mVerticesChoppyBuffer(0)
, mDisplacement(Displacement)
{
setOptions(Options);
}

CustomGrid::~CustomGrid()
{
remove();

HydraxLOG(getName() + " destroyed.");
}

void CustomGrid::setOptions(const Options &Options)
{
mMeshOptions.MeshSize = Options.MeshSize;
mMeshOptions.MeshStrength = Options.Strength;
mMeshOptions.MeshComplexity = Options.Complexity;
mDisplacement = Options.Displacement;
mHydrax->getMesh()->setOptions(mMeshOptions);
mHydrax->_setStrength(Options.Strength);

if (isCreated())
{
if (Options.Complexity != mOptions.Complexity || Options.ChoppyWaves != Options.ChoppyWaves)
{
remove();
mOptions = Options;
create();

if (mNormalMode == MaterialManager::NM_RTT)
{
if (!mNoise->createGPUNormalMapResources(mHydrax->getGPUNormalMapManager()))
{
HydraxLOG(mNoise->getName() + " doesn't support GPU Normal map generation.");
}
}

Ogre::String MaterialNameTmp = mHydrax->getMesh()->getMaterialName();
mHydrax->getMesh()->remove();

mHydrax->getMesh()->setOptions(getMeshOptions());
mHydrax->getMesh()->setMaterialName(MaterialNameTmp);
mHydrax->getMesh()->create();

return;
}

mOptions = Options;

int v, u;
if (getNormalMode() == MaterialManager::NM_VERTEX)
{
Mesh::POS_NORM_VERTEX* Vertices = static_cast<Mesh::POS_NORM_VERTEX*>(mVertices);

for(v=0; v<mOptions.Complexity; v++)
{
//float rowDisplacement = mOptions.MeshSize.Width - (mDisplacement - abs(((mDisplacement/mOptions.Complexity)*(2*v))-mDisplacement));
float rowDisplacement = mOptions.MeshSize.Width - (mDisplacement*Ogre::Math::Sin(Ogre::Math::PI*v/mOptions.Complexity));

for(u=0; u<mOptions.Complexity; u++)
{
Vertices[v*mOptions.Complexity + u].x = (static_cast<float>(v)/(mOptions.Complexity-1)) * mOptions.MeshSize.Width;
Vertices[v*mOptions.Complexity + u].z = (static_cast<float>(u)/(mOptions.Complexity-1)) * rowDisplacement;
}
}

if (mOptions.ChoppyWaves && mVerticesChoppyBuffer)
{
for(int i = 0; i < mOptions.Complexity*mOptions.Complexity; i++)
{
mVerticesChoppyBuffer[i] = Vertices[i];
}
}
}
else if (getNormalMode() == MaterialManager::NM_RTT)
{
Mesh::POS_VERTEX* Vertices = static_cast<Mesh::POS_VERTEX*>(mVertices);

for(v=0; v<mOptions.Complexity; v++)
{
//float rowDisplacement = mOptions.MeshSize.Width - (mDisplacement - abs(((mDisplacement/mOptions.Complexity)*(2*v))-mDisplacement));
float rowDisplacement = mOptions.MeshSize.Width - (mDisplacement*Ogre::Math::Sin(Ogre::Math::PI*v/mOptions.Complexity));

for(u=0; u<mOptions.Complexity; u++)
{
Vertices[v*mOptions.Complexity + u].x = (static_cast<float>(v)/(mOptions.Complexity-1)) * mOptions.MeshSize.Width;
Vertices[v*mOptions.Complexity + u].z = (static_cast<float>(u)/(mOptions.Complexity-1)) * rowDisplacement;
}
}
}

return;
}

mOptions = Options;
}

void CustomGrid::create()
{
HydraxLOG("Creating " + getName() + " module.");

Module::create();

int v, u;
if (getNormalMode() == MaterialManager::NM_VERTEX)
{
mVertices = new Mesh::POS_NORM_VERTEX[mOptions.Complexity*mOptions.Complexity];
Mesh::POS_NORM_VERTEX* Vertices = static_cast<Mesh::POS_NORM_VERTEX*>(mVertices);

for(v=0; v<mOptions.Complexity; v++)
{
//float rowDisplacement = mOptions.MeshSize.Width - (mDisplacement - abs(((mDisplacement/mOptions.Complexity)*(2*v))-mDisplacement));
float rowDisplacement = mOptions.MeshSize.Width - (mDisplacement*Ogre::Math::Sin(Ogre::Math::PI*v/mOptions.Complexity));

for(u=0; u<mOptions.Complexity; u++)
{
Vertices[v*mOptions.Complexity + u].x = (static_cast<float>(v)/(mOptions.Complexity-1)) * mOptions.MeshSize.Width;
Vertices[v*mOptions.Complexity + u].z = (static_cast<float>(u)/(mOptions.Complexity-1)) * rowDisplacement;
Vertices[v*mOptions.Complexity + u].nx = 0;
Vertices[v*mOptions.Complexity + u].ny = -1;
Vertices[v*mOptions.Complexity + u].nz = 0;
}
}

if (mOptions.ChoppyWaves)
{
mVerticesChoppyBuffer = new Mesh::POS_NORM_VERTEX[mOptions.Complexity*mOptions.Complexity];

for(int i = 0; i < mOptions.Complexity*mOptions.Complexity; i++)
{
mVerticesChoppyBuffer[i] = Vertices[i];
}
}
}
else if (getNormalMode() == MaterialManager::NM_RTT)
{
mVertices = new Mesh::POS_VERTEX[mOptions.Complexity*mOptions.Complexity];
Mesh::POS_VERTEX* Vertices = static_cast<Mesh::POS_VERTEX*>(mVertices);

for(v=0; v<mOptions.Complexity; v++)
{
//float rowDisplacement = mOptions.MeshSize.Width - (mDisplacement - abs(((mDisplacement/mOptions.Complexity)*(2*v))-mDisplacement));
float rowDisplacement = mOptions.MeshSize.Width - (mDisplacement*Ogre::Math::Sin(Ogre::Math::PI*v/mOptions.Complexity));

for(u=0; u<mOptions.Complexity; u++)
{
Vertices[v*mOptions.Complexity + u].x = (static_cast<float>(v)/(mOptions.Complexity-1)) * mOptions.MeshSize.Width;
Vertices[v*mOptions.Complexity + u].z = (static_cast<float>(u)/(mOptions.Complexity-1)) * rowDisplacement;
}
}
}

HydraxLOG(getName() + " created.");
}

void CustomGrid::remove()
{
if (!isCreated())
{
return;
}

Module::remove();

if (mVertices)
{
if (getNormalMode() == MaterialManager::NM_VERTEX)
{
delete [] static_cast<Mesh::POS_NORM_VERTEX*>(mVertices);
}
else if (getNormalMode() == MaterialManager::NM_RTT)
{
delete [] static_cast<Mesh::POS_VERTEX*>(mVertices);
}
}

if (mVerticesChoppyBuffer)
{
delete [] mVerticesChoppyBuffer;
}
}

void CustomGrid::saveCfg(Ogre::String &Data)
{
Module::saveCfg(Data);

Data += CfgFileManager::_getCfgString("SG_Complexity", mOptions.Complexity);
Data += CfgFileManager::_getCfgString("SG_MeshSize", mOptions.MeshSize);
Data += CfgFileManager::_getCfgString("SG_Strength", mOptions.Strength);
Data += CfgFileManager::_getCfgString("SG_Smooth", mOptions.Smooth);
Data += CfgFileManager::_getCfgString("SG_ChoppyWaves", mOptions.ChoppyWaves);
Data += CfgFileManager::_getCfgString("SG_ChoppyStrength", mOptions.ChoppyStrength); Data += "\n";
}

bool CustomGrid::loadCfg(Ogre::ConfigFile &CfgFile)
{
if (!Module::loadCfg(CfgFile))
{
return false;
}

setOptions(
Options(CfgFileManager::_getIntValue(CfgFile, "SG_Complexity"),
CfgFileManager::_getSizeValue(CfgFile, "SG_MeshSize"),
CfgFileManager::_getFloatValue(CfgFile, "SG_Strength"),
CfgFileManager::_getBoolValue(CfgFile, "PG_Smooth"),
CfgFileManager::_getBoolValue(CfgFile, "PG_ChoppyWaves"),
CfgFileManager::_getFloatValue(CfgFile, "PG_ChoopyStrength")));

return true;
}

void CustomGrid::update(const Ogre::Real &timeSinceLastFrame)
{
if (!isCreated())
{
return;
}

Module::update(timeSinceLastFrame);

// Update heigths
int i = 0, v, u;

if (getNormalMode() == MaterialManager::NM_VERTEX)
{
Mesh::POS_NORM_VERTEX* Vertices = static_cast<Mesh::POS_NORM_VERTEX*>(mVertices);

if (mOptions.ChoppyWaves)
{
for(int i = 0; i < mOptions.Complexity*mOptions.Complexity; i++)
{
Vertices[i] = mVerticesChoppyBuffer[i];
Vertices[i].y = mNoise->getValue(Vertices[i].x, Vertices[i].z) * mOptions.Strength;
}
}
else
{
for(int i = 0; i < mOptions.Complexity*mOptions.Complexity; i++)
{
Vertices[i].y = mNoise->getValue(Vertices[i].x, Vertices[i].z) * mOptions.Strength;
}
}
}
else if (getNormalMode() == MaterialManager::NM_RTT)
{
Mesh::POS_VERTEX* Vertices = static_cast<Mesh::POS_VERTEX*>(mVertices);

// For object-space to world-space conversion
// RTT normals calculation needs world-space coords
Ogre::Vector3 p = Ogre::Vector3(0,0,0);
Ogre::Matrix4 mWorldMatrix;
mHydrax->getMesh()->getEntity()->getParentSceneNode()->getWorldTransforms(&mWorldMatrix);

for(int i = 0; i < mOptions.Complexity*mOptions.Complexity; i++)
{
p.x = Vertices[i].x;
p.y = 0;
p.z = Vertices[i].z;

// Calculate the world-space position
mWorldMatrix.transformAffine(p);

Vertices[i].y = mNoise->getValue(p.x, p.z) * mOptions.Strength;
}
}

// Smooth the heightdata
if (mOptions.Smooth)
{
if (getNormalMode() == MaterialManager::NM_VERTEX)
{
Mesh::POS_NORM_VERTEX* Vertices = static_cast<Mesh::POS_NORM_VERTEX*>(mVertices);

for(v=1; v<(mOptions.Complexity-1); v++)
{
for(u=1; u<(mOptions.Complexity-1); u++)
{
Vertices[v*mOptions.Complexity + u].y =
0.2f *
(Vertices[v *mOptions.Complexity + u ].y +
Vertices[v *mOptions.Complexity + (u+1)].y +
Vertices[v *mOptions.Complexity + (u-1)].y +
Vertices[(v+1)*mOptions.Complexity + u ].y +
Vertices[(v-1)*mOptions.Complexity + u ].y);
}
}
}
else if (getNormalMode() == MaterialManager::NM_RTT)
{
Mesh::POS_VERTEX* Vertices = static_cast<Mesh::POS_VERTEX*>(mVertices);

for(v=1; v<(mOptions.Complexity-1); v++)
{
for(u=1; u<(mOptions.Complexity-1); u++)
{
Vertices[v*mOptions.Complexity + u].y =
0.2f *
(Vertices[v *mOptions.Complexity + u ].y +
Vertices[v *mOptions.Complexity + (u+1)].y +
Vertices[v *mOptions.Complexity + (u-1)].y +
Vertices[(v+1)*mOptions.Complexity + u ].y +
Vertices[(v-1)*mOptions.Complexity + u ].y);
}
}
}
}

// Update normals
_calculeNormals();

// Perform choppy waves
_performChoppyWaves();

// Upload geometry changes
mHydrax->getMesh()->updateGeometry(mOptions.Complexity*mOptions.Complexity, mVertices);
}

void CustomGrid::_calculeNormals()
{
if (getNormalMode() != MaterialManager::NM_VERTEX)
{
return;
}

int v, u;
Ogre::Vector3 vec1, vec2, normal;

Mesh::POS_NORM_VERTEX* Vertices = static_cast<Mesh::POS_NORM_VERTEX*>(mVertices);

for(v=1; v<(mOptions.Complexity-1); v++)
{
for(u=1; u<(mOptions.Complexity-1); u++)
{
vec1 = Ogre::Vector3(
Vertices[v*mOptions.Complexity + u + 1].x-Vertices[v*mOptions.Complexity + u - 1].x,
Vertices[v*mOptions.Complexity + u + 1].y-Vertices[v*mOptions.Complexity + u - 1].y,
Vertices[v*mOptions.Complexity + u + 1].z-Vertices[v*mOptions.Complexity + u - 1].z);

vec2 = Ogre::Vector3(
Vertices[(v+1)*mOptions.Complexity + u].x - Vertices[(v-1)*mOptions.Complexity + u].x,
Vertices[(v+1)*mOptions.Complexity + u].y - Vertices[(v-1)*mOptions.Complexity + u].y,
Vertices[(v+1)*mOptions.Complexity + u].z - Vertices[(v-1)*mOptions.Complexity + u].z);

normal = vec2.crossProduct(vec1);

Vertices[v*mOptions.Complexity + u].nx = normal.x;
Vertices[v*mOptions.Complexity + u].ny = normal.y;
Vertices[v*mOptions.Complexity + u].nz = normal.z;
}
}
}

void CustomGrid::_performChoppyWaves()
{
if (getNormalMode() != MaterialManager::NM_VERTEX || !mOptions.ChoppyWaves)
{
return;
}

int v, u,
Underwater = 1;

if (mHydrax->_isCurrentFrameUnderwater())
{
Underwater = -1;
}

Mesh::POS_NORM_VERTEX* Vertices = static_cast<Mesh::POS_NORM_VERTEX*>(mVertices);

for(v=1; v<(mOptions.Complexity-1); v++)
{
for(u=1; u<(mOptions.Complexity-1); u++)
{
Vertices[v*mOptions.Complexity + u].x += Vertices[v*mOptions.Complexity + u].nx * mOptions.ChoppyStrength * Underwater;
Vertices[v*mOptions.Complexity + u].z += Vertices[v*mOptions.Complexity + u].nz * mOptions.ChoppyStrength * Underwater;
}
}
}

float CustomGrid::getHeigth(const Ogre::Vector2 &Position)
{
if (getNormalMode() != MaterialManager::NM_RTT)
{
Ogre::Vector2 RelativePos = mHydrax->getMesh()->getGridPosition(Position);

RelativePos.x *= mOptions.MeshSize.Width;
RelativePos.y *= mOptions.MeshSize.Height;

return mHydrax->getPosition().y + mNoise->getValue(RelativePos.x, RelativePos.y)*mOptions.Strength;
}
else // RTT Normals calculations works with world-space coords
{
return mHydrax->getPosition().y + mNoise->getValue(Position.x, Position.y)*mOptions.Strength;
}
}


}}



I have made some changes on the code to change the curve shape.I will post it soon

SFCBias

29-05-2010 08:10:10

Use code tags please

kARUN4

29-05-2010 18:13:58

Done!