1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-10-05 06:26:31 +00:00
openmw-tes3mp/terrain/cpp_terrainmesh.h
2009-05-15 07:04:50 +00:00

229 lines
6.7 KiB
C++

/**
* @brief Terrain for one cell. Handles building, destroying and LOD morphing
*/
class TerrainRenderable : public Ogre::Renderable, public Ogre::MovableObject {
public:
explicit TerrainRenderable(Terrain* t, QuadSegment* qs, int width, int depth, bool skirts);
/**
* Calls destroy();
*/
~TerrainRenderable();
/**
* Creates the actual mesh, it has to be called manually, as it is not called in the constructor
*/
void create(Ogre::SceneNode* sn) ;
/**
* Can be called manually and can be called from the destuctor. This destroyes the mesh
*/
void destroy();
/**
* @brief Checks if it needs to be split or unsplit and deals with the morph factor
* @brief time seconds since last frame
*/
void update(Ogre::Real time, Ogre::Real camDist, Ogre::Real usplitDist, Ogre::Real morphDist);
/**
* @todo Needs to work out what this does (if it does what it is meant to)
*/
void visitRenderables(Renderable::Visitor* visitor,
bool debugRenderables = false) {
visitor->visit(this, 0, false);
}
virtual const Ogre::MaterialPtr& getMaterial( void ) const {
return mMaterial;
}
//-----------------------------------------------------------------------
void getRenderOperation( Ogre::RenderOperation& op ) {
op.useIndexes = true;
op.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
op.vertexData = mVertexes;
op.indexData = mIndices;
}
//-----------------------------------------------------------------------
void getWorldTransforms( Ogre::Matrix4* xform ) const {
*xform = mParentNode->_getFullTransform();
}
//-----------------------------------------------------------------------
const Ogre::Quaternion& getWorldOrientation(void) const {
return mParentNode->_getDerivedOrientation();
}
//-----------------------------------------------------------------------
const Ogre::Vector3& getWorldPosition(void) const {
return mParentNode->_getDerivedPosition();
}
//-----------------------------------------------------------------------
Ogre::Real getSquaredViewDepth(const Ogre::Camera *cam) const {
Ogre::Vector3 diff = mCenter - cam->getDerivedPosition();
// Use squared length to avoid square root
return diff.squaredLength();
}
//-----------------------------------------------------------------------
const Ogre::LightList& getLights(void) const {
if (mLightListDirty) {
getParentSceneNode()->getCreator()->_populateLightList(
mCenter, this->getBoundingRadius(), mLightList);
mLightListDirty = false;
}
return mLightList;
}
//-----------------------------------------------------------------------
virtual const Ogre::String& getMovableType( void ) const {
static Ogre::String t = "MW_TERRAIN";
return t;
}
//-----------------------------------------------------------------------
void _updateRenderQueue( Ogre::RenderQueue* queue ) {
mLightListDirty = true;
queue->addRenderable(this, mRenderQueueID);
}
const Ogre::AxisAlignedBox& getBoundingBox( void ) const {
return mBounds;
};
//-----------------------------------------------------------------------
Ogre::Real getBoundingRadius(void) const {
return mBoundingRadius;
}
//-----------------------------------------------------------------------
/**
* @brief passes the morph factor to the custom vertex program
*/
void _updateCustomGpuParameter(const Ogre::GpuProgramParameters::AutoConstantEntry& constantEntry,
Ogre::GpuProgramParameters* params) const;
/**
* @brief sets the mExtraMorphAmount so it slowly regains detail from the lowest morph factor
*/
void justSplit();
/**
* @brief Does nothing
*/
inline void justUnsplit(){
}
inline float getMax(){
return mMax;
}
inline float getMin(){
return mMin;
}
private:
/**
* @brief Adds another pass to the material to fade in/out the material from a higher level
*/
void addFadePass();
/**
* @brief removes the last pass from the material. Assumed to be the fade pass
*/
void removeFadePass();
/**
* @return the height at the given vertex
*/
float getVertexHeight(int x, int y);
/**
* Inits the vertex stuff
*/
void createVertexBuffer();
/**
* @brief fills the vertex buffer with data
* @todo I don't think tex co-ords are right
*/
void calculateVetexValues();
/**
* @brief returns a a new Vertex Buffer ready for input
* @remarks Unlike other terrain libs, this isn't 0s when it is returend
*/
Ogre::HardwareVertexBufferSharedPtr createDeltaBuffer( );
/**
* @brief DOESN'T WORK FULLY
* @todo fix
*/
void calculateDeltaValues();
/**
* @brief gets the position of a vertex. It will not interpolate
*/
Ogre::Vector3 getVertexPosition(int x, int y);
/**
* @brief gets the indicies for the vertex data.
*/
void calculateIndexValues();
/**
* @brief sets the bounds on the renderable. This requires that mMin/mMax have been set. They are set in createVertexData
* @remarks this may look as though it is done twice, as it is also done in MeshInterface, however, there is no guarentee that
* the mesh sizes are the same
*/
void setBounds();
const int mWidth;
const bool mUseSkirts;
///true if the land has been built
bool mBuilt;
int mDepth;
QuadSegment* mSegment;
Terrain* mTerrain;
Ogre::MaterialPtr mMaterial;
Ogre::ManualObject* mObject;
Ogre::SceneNode* mSceneNode;
Ogre::VertexData* mVertexes;
Ogre::IndexData* mIndices;
Ogre::HardwareVertexBufferSharedPtr mMainBuffer;
Ogre::HardwareVertexBufferSharedPtr mDeltaBuffer;
mutable bool mLightListDirty;
Ogre::Real mBoundingRadius;
Ogre::AxisAlignedBox mBounds;
Ogre::Vector3 mCenter;
Ogre::Real mLODMorphFactor, mTextureFadeFactor;
/** Max and min heights of the mesh */
float mMin, mMax;
/**
* @brief holds the amount to morph by, this decreases to 0 over a periord of time
* It is changed and used in the update() function
*/
Ogre::Real mExtraMorphAmount, mExtraFadeAmount;
/**
* True if the fade pass has been added to the material.
*/
bool mHasFadePass;
//Custom params used in terrian shaders.
static const size_t MORPH_CUSTOM_PARAM_ID = 77;
static const size_t FADE_CUSTOM_PARAM_ID = 78;
//Terrain bindings
static const int MAIN_BINDING = 0;
static const int DELTA_BINDING = 1;
};