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
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?
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