Skip to content

Instantly share code, notes, and snippets.

@andr3wmac
Created April 23, 2014 23:54
Show Gist options
  • Save andr3wmac/11236602 to your computer and use it in GitHub Desktop.
Save andr3wmac/11236602 to your computer and use it in GitHub Desktop.
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// andrewmac: made a change in setupVertexBlock to change corners into
// hexagon shape.
#include "platform/platform.h"
#include "WaterHexagon.h"
#include "core/util/safeDelete.h"
#include "scene/sceneRenderState.h"
#include "scene/sceneManager.h"
#include "lighting/lightInfo.h"
#include "core/stream/bitStream.h"
#include "math/mathIO.h"
#include "console/consoleTypes.h"
#include "gui/3d/guiTSControl.h"
#include "gfx/primBuilder.h"
#include "gfx/gfxTransformSaver.h"
#include "gfx/gfxDebugEvent.h"
#include "gfx/gfxOcclusionQuery.h"
#include "renderInstance/renderPassManager.h"
#include "sim/netConnection.h"
#include "scene/reflectionManager.h"
#include "ts/tsShapeInstance.h"
#include "postFx/postEffect.h"
#include "math/util/matrixSet.h"
IMPLEMENT_CO_NETOBJECT_V1(WaterHexagon);
ConsoleDocClass( WaterHexagon,
"@brief A block shaped water volume defined by a 3D scale and orientation.\n\n"
"@see WaterObject for inherited functionality.\n\n"
"@ingroup Water"
);
WaterHexagon::WaterHexagon()
{
mGridElementSize = 5.0f;
mObjScale.set( 100.0f, 100.0f, 10.0f );
mNetFlags.set(Ghostable | ScopeAlways);
mObjBox.minExtents.set( -0.5f, -0.5f, -0.5f );
mObjBox.maxExtents.set( 0.5f, 0.5f, 0.5f );
mElapsedTime = 0.0f;
mGenerateVB = true;
}
WaterHexagon::~WaterHexagon()
{
}
bool WaterHexagon::onAdd()
{
if ( !Parent::onAdd() )
return false;
resetWorldBox();
addToScene();
return true;
}
void WaterHexagon::onRemove()
{
clearVertBuffers();
removeFromScene();
Parent::onRemove();
}
//-----------------------------------------------------------------------------
// packUpdate
//-----------------------------------------------------------------------------
U32 WaterHexagon::packUpdate(NetConnection* con, U32 mask, BitStream* stream)
{
U32 retMask = Parent::packUpdate(con, mask, stream);
stream->write( mGridElementSize );
if ( stream->writeFlag( mask & UpdateMask ) )
{
// This is set to allow the user to modify the size of the water dynamically
// in the editor
mathWrite( *stream, mObjScale );
stream->writeAffineTransform( mObjToWorld );
}
return retMask;
}
//-----------------------------------------------------------------------------
// unpackUpdate
//-----------------------------------------------------------------------------
void WaterHexagon::unpackUpdate(NetConnection* con, BitStream* stream)
{
Parent::unpackUpdate(con, stream);
F32 gridSize = mGridElementSize;
stream->read( &mGridElementSize );
if ( gridSize != mGridElementSize )
mGenerateVB = true;
if( stream->readFlag() ) // UpdateMask
{
Point3F scale;
mathRead( *stream, &scale );
setScale( scale );
MatrixF objToWorld;
stream->readAffineTransform( &objToWorld );
setTransform( objToWorld );
}
}
//-----------------------------------------------------------------------------
// Setup vertex and index buffers
//-----------------------------------------------------------------------------
void WaterHexagon::setupVBIB()
{
clearVertBuffers();
const U32 maxIndexedVerts = 65536; // max number of indexed verts with U16 size indices
if( mObjScale.x < mGridElementSize ||
mObjScale.y < mGridElementSize )
{
F32 oldGridSize = mGridElementSize;
mGridElementSize = getMin(mObjScale.x, mObjScale.y);
logWarning("gridElementSize %g is larger than scale (%g, %g), clamping gridElementSize to %g",
oldGridSize, mObjScale.x, mObjScale.y, mGridElementSize);
}
Point3F div = getScale() / mGridElementSize;
// Add one to width and height for the edge.
mWidth = (U32)mCeil(div.x) + 1;
mHeight = (U32)mCeil(div.y) + 1;
if( mWidth > maxIndexedVerts / 2 )
mWidth = maxIndexedVerts / 2;
// figure out how many blocks are needed and their size
U32 maxBlockRows = maxIndexedVerts / mWidth;
U32 rowOffset = 0;
while( (rowOffset+1) < mHeight )
{
U32 numRows = mHeight - rowOffset;
if( numRows == 1 ) numRows++;
if( numRows > maxBlockRows )
{
numRows = maxBlockRows;
}
setupVertexBlock( mWidth, numRows, rowOffset );
setupPrimitiveBlock( mWidth, numRows );
rowOffset += numRows - 1;
}
}
//-----------------------------------------------------------------------------
// Set up a block of vertices - the width is always the width of the entire
// WaterHexagon, so this is a block of full rows.
//-----------------------------------------------------------------------------
void WaterHexagon::setupVertexBlock( U32 width, U32 height, U32 rowOffset )
{
Point3F pos = getPosition();
RayInfo rInfo;
VectorF sunVector(-0.61f, 0.354f, 0.707f);
if ( LIGHTMGR )
{
LightInfo* linfo = LIGHTMGR->getSpecialLight( LightManager::slSunLightType );
if ( linfo )
sunVector = linfo->getDirection();
}
sunVector.normalize();
U32 numVerts = width * height;// -4;
GFXWaterVertex *verts = new GFXWaterVertex[ numVerts ];
ColorI waterColor(31, 56, 64, 127);
GFXVertexColor vertCol(waterColor);
U32 index = 0;
for( U32 i=0; i<height; i++ )
{
for( U32 j=0; j<width; j++, index++ )
{
F32 vertX = (-mObjScale.x / 2.0f) + mGridElementSize * j;
F32 vertY = (-mObjScale.y / 2.0f) + mGridElementSize * i;
GFXWaterVertex *vert = &verts[index];
vert->point.x = vertX;
vert->point.y = vertY;
vert->point.z = 0.0;
vert->color = vertCol;
vert->normal.set(0,0,1);
vert->undulateData.set( vertX, vertY );
vert->horizonFactor.set( 0, 0, 0, 0 );
// andrewmac: Hexagon Corners
if (i == 0 && j == 0)
{
vert->point.x = vertX + mGridElementSize;
vert->point.y = vertY + mGridElementSize;
}
if (i == (height - 1) && j == 0)
{
vert->point.x = vertX + (mGridElementSize / 2.0f);
vert->point.y = vertY - (mGridElementSize / 2.0f);
}
if (i == 0 && j == (width - 1))
{
vert->point.x = vertX - (mGridElementSize / 2.0f);
vert->point.y = vertY + (mGridElementSize / 2.0f);
}
if (i == (height - 1) && j == (width - 1))
{
vert->point.x = vertX - mGridElementSize;
vert->point.y = vertY - mGridElementSize;
}
}
}
// copy to vertex buffer
GFXVertexBufferHandle <GFXWaterVertex> * vertBuff = new GFXVertexBufferHandle <GFXWaterVertex>;
vertBuff->set( GFX, numVerts, GFXBufferTypeStatic );
GFXWaterVertex *vbVerts = vertBuff->lock();
dMemcpy( vbVerts, verts, sizeof(GFXWaterVertex) * numVerts );
vertBuff->unlock();
mVertBuffList.push_back( vertBuff );
delete [] verts;
}
//-----------------------------------------------------------------------------
// Set up a block of indices to match the block of vertices. The width is
// always the width of the entire WaterHexagon, so this is a block of full rows.
//-----------------------------------------------------------------------------
void WaterHexagon::setupPrimitiveBlock( U32 width, U32 height )
{
AssertFatal( height > 1, "WaterHexagon::setupPrimitiveBlock() - invalid height" );
// setup vertex / primitive buffers
U32 numIndices = (width - 1) * (height - 1) * 6;// -(4 * 6);
U16 *indices = new U16[ numIndices ];
U32 numVerts = width * height;// -4;
// This uses indexed triangle lists instead of strips, but it shouldn't be
// significantly slower if the indices cache well.
// Rough diagram of the index order
// 0----2----+ ...
// | / | |
// |/ | |
// 1----3----+ ...
// | | |
// | | |
// +----+----+ ...
U32 index = 0;
for( U32 i=0; i<(height-1); i++ )
{
for( U32 j=0; j<(width-1); j++, index+=6 )
{
// Process one quad at a time. Note it will re-use the same indices from
// previous quad, thus optimizing vert cache. Cache will run out at
// end of each row with this implementation however.
indices[index+0] = (i) * mWidth + j; // 0
indices[index+1] = (i+1) * mWidth + j; // 1
indices[index+2] = i * mWidth + j+1; // 2
indices[index+3] = (i+1) * mWidth + j; // 1
indices[index+4] = (i+1) * mWidth + j+1; // 3
indices[index+5] = i * mWidth + j+1; // 2
}
}
GFXPrimitiveBufferHandle *indexBuff = new GFXPrimitiveBufferHandle;
GFXPrimitive pInfo;
pInfo.type = GFXTriangleList;
pInfo.numPrimitives = numIndices / 3;
pInfo.startIndex = 0;
pInfo.minIndex = 0;
pInfo.numVertices = numVerts;
U16 *ibIndices;
GFXPrimitive *piInput;
indexBuff->set( GFX, numIndices, 1, GFXBufferTypeStatic );
indexBuff->lock( &ibIndices, &piInput );
dMemcpy( ibIndices, indices, numIndices * sizeof(U16) );
dMemcpy( piInput, &pInfo, sizeof(GFXPrimitive) );
indexBuff->unlock();
mPrimBuffList.push_back( indexBuff );
delete [] indices;
}
//------------------------------------------------------------------------------
// Setup scenegraph data structure for materials
//------------------------------------------------------------------------------
SceneData WaterHexagon::setupSceneGraphInfo( SceneRenderState *state )
{
SceneData sgData;
sgData.lights[0] = LIGHTMGR->getSpecialLight( LightManager::slSunLightType );
// fill in water's transform
sgData.objTrans = &getRenderTransform();
// fog
sgData.setFogParams( state->getSceneManager()->getFogData() );
// misc
sgData.backBuffTex = REFLECTMGR->getRefractTex();
sgData.reflectTex = mPlaneReflector.reflectTex;
sgData.wireframe = GFXDevice::getWireframe() || smWireframe;
return sgData;
}
//-----------------------------------------------------------------------------
// set shader parameters
//-----------------------------------------------------------------------------
void WaterHexagon::setShaderParams( SceneRenderState *state, BaseMatInstance *mat, const WaterMatParams &paramHandles)
{
// Set variables that will be assigned to shader consts within WaterCommon
// before calling Parent::setShaderParams
mUndulateMaxDist = F32_MAX;
Parent::setShaderParams( state, mat, paramHandles );
// Now set the rest of the shader consts that are either unique to this
// class or that WaterObject leaves to us to handle...
MaterialParameters* matParams = mat->getMaterialParameters();
// set vertex shader constants
//-----------------------------------
MatrixF modelMat( getRenderTransform() );
if ( paramHandles.mModelMatSC->isValid() )
matParams->set(paramHandles.mModelMatSC, modelMat, GFXSCT_Float4x4);
matParams->setSafe(paramHandles.mGridElementSizeSC, (F32)mGridElementSize);
// set pixel shader constants
//-----------------------------------
ColorF c( mWaterFogData.color );
matParams->setSafe( paramHandles.mBaseColorSC, c );
// By default we need to show a true reflection is fullReflect is enabled and
// we are above water.
F32 reflect = mPlaneReflector.isEnabled() && !isUnderwater( state->getCameraPosition() );
// If we were occluded the last frame a query was fetched ( not necessarily last frame )
// and we weren't updated last frame... we don't have a valid texture to show
// so use the cubemap / fake reflection color this frame.
if ( mPlaneReflector.lastUpdateMs != REFLECTMGR->getLastUpdateMs() && mPlaneReflector.isOccluded() )
reflect = false;
Point4F reflectParams( mWaterPos.z, 0.0f, 1000.0f, !reflect );
matParams->setSafe( paramHandles.mReflectParamsSC, reflectParams );
VectorF reflectNorm = mReflectNormalUp ? VectorF(0,0,1) : static_cast<VectorF>(mPlaneReflector.refplane);
matParams->setSafe(paramHandles.mReflectNormalSC, reflectNorm );
}
void WaterHexagon::innerRender( SceneRenderState *state )
{
GFXDEBUGEVENT_SCOPE( WaterHexagon_innerRender, ColorI( 255, 0, 0 ) );
if ( mGenerateVB )
{
setupVBIB();
mGenerateVB = false;
}
// Setup SceneData
SceneData sgData = setupSceneGraphInfo( state );
const Point3F &camPosition = state->getCameraPosition();
// set the material
S32 matIdx = getMaterialIndex( camPosition );
if ( !initMaterial( matIdx ) )
return;
BaseMatInstance *mat = mMatInstances[matIdx];
WaterMatParams matParams = mMatParamHandles[matIdx];
// render the geometry
if ( mat )
{
// setup proj/world transform
mMatrixSet->setWorld(getRenderTransform());
mMatrixSet->restoreSceneViewProjection();
setShaderParams( state, mat, matParams );
while ( mat->setupPass( state, sgData ) )
{
mat->setSceneInfo(state, sgData);
mat->setTransforms(*mMatrixSet, state);
setCustomTextures( matIdx, mat->getCurPass(), matParams );
for ( U32 i = 0; i < mVertBuffList.size(); i++ )
{
GFX->setVertexBuffer( *mVertBuffList[i] );
GFXPrimitiveBuffer *primBuff = *mPrimBuffList[i];
GFX->setPrimitiveBuffer( primBuff );
GFX->drawPrimitives();
}
}
}
}
bool WaterHexagon::setGridSizeProperty( void *obj, const char *index, const char *data )
{
WaterHexagon* object = static_cast<WaterHexagon*>(obj);
F32 gridSize = dAtof(data);
Point3F scale = object->getScale();
if(gridSize < 0.001f)
{
object->logWarning("gridSize cannot be <= 0, clamping to scale");
gridSize = getMin(scale.x, scale.y);
}
if(gridSize > scale.x || gridSize > scale.y)
{
object->logWarning("gridSize cannot be > scale. Your scale is (%g, %g) and your gridsize is %g",
scale.x, scale.y, gridSize);
gridSize = getMin(scale.x, scale.y);
}
object->mGridElementSize = gridSize;
// This is a hack so the console system doesn't go in and set our variable
// again, after we've already set it (possibly with a different value...)
return false;
}
//-----------------------------------------------------------------------------
// initPersistFields
//-----------------------------------------------------------------------------
void WaterHexagon::initPersistFields()
{
addGroup( "WaterHexagon" );
addProtectedField( "gridElementSize", TypeF32, Offset( mGridElementSize, WaterHexagon ),
&setGridSizeProperty, &defaultProtectedGetFn, "Spacing between vertices in the WaterHexagon mesh" );
addProtectedField( "gridSize", TypeF32, Offset( mGridElementSize, WaterHexagon ),
&setGridSizeProperty, &defaultProtectedGetFn, "Duplicate of gridElementSize for backwards compatility" );
endGroup( "WaterHexagon" );
Parent::initPersistFields();
}
bool WaterHexagon::isUnderwater( const Point3F &pnt ) const
{
// Transform point into object space so we can test if it is within
// the WaterHexagon's object box, include rotation/scale.
Point3F objPnt = pnt;
mWorldToObj.mulP( pnt, &objPnt );
objPnt.z -= 0.1f;
Box3F testBox = mObjBox;
testBox.scale( mObjScale );
// We already tested if below the surface plane,
// so clamping the z height of the box is not really necessary.
testBox.maxExtents.z = testBox.getCenter().z;
if ( testBox.isContained( objPnt ) )
return true;
return false;
}
void WaterHexagon::clearVertBuffers()
{
for( U32 i=0; i<mVertBuffList.size(); i++ )
delete mVertBuffList[i];
mVertBuffList.clear();
for( U32 i=0; i<mPrimBuffList.size(); i++ )
delete mPrimBuffList[i];
mPrimBuffList.clear();
}
void WaterHexagon::inspectPostApply()
{
Parent::inspectPostApply();
VectorF scale = getScale();
if( scale.x < mGridElementSize )
scale.x = mGridElementSize;
if( scale.y < mGridElementSize )
scale.y = mGridElementSize;
if( scale != getScale() )
setScale( scale );
setMaskBits( UpdateMask );
}
void WaterHexagon::setTransform( const MatrixF &mat )
{
// If our transform changes we need to recalculate the
// per vertex depth/shadow info. Would be nice if this could
// be done independently of generating the whole VBIB...
MatrixF oldMat = mObjToWorld;
Parent::setTransform( mat );
// We don't need to regen our vb anymore since we aren't calculating
// per vert depth/shadow on the cpu anymore.
//if ( oldMat != mObjToWorld )
// mGenerateVB = true;
// Keep mWaterPlane up to date.
mWaterFogData.plane.set( 0, 0, 1, -getPosition().z );
}
void WaterHexagon::setScale( const Point3F &scale )
{
Point3F oldScale = mObjScale;
Parent::setScale( scale );
if ( oldScale != mObjScale )
mGenerateVB = true;
}
void WaterHexagon::onStaticModified( const char* slotName, const char*newValue )
{
Parent::onStaticModified( slotName, newValue );
if ( dStricmp( slotName, "surfMaterial" ) == 0 )
setMaskBits( MaterialMask );
if ( dStricmp( slotName, "gridElementSize" ) == 0 )
{
mGenerateVB = true;
setMaskBits( UpdateMask );
}
}
bool WaterHexagon::castRay( const Point3F &start, const Point3F &end, RayInfo *info )
{
// Simply look for the hit on the water plane
// and ignore any future issues with waves, etc.
const Point3F norm(0,0,1);
PlaneF plane( Point3F::Zero, norm );
F32 hit = plane.intersect( start, end );
if ( hit < 0.0f || hit > 1.0f )
return false;
info->t = hit;
info->object = this;
info->point = start + ( ( end - start ) * hit );
info->normal = norm;
info->material = mMatInstances[WaterMat];
return mObjBox.isContained(info->point);
}
F32 WaterHexagon::getWaterCoverage( const Box3F &testBox ) const
{
Box3F wbox = getWorldBox();
wbox.maxExtents.z = wbox.getCenter().z;
F32 coverage = 0.0f;
if ( wbox.isOverlapped(testBox) )
{
if (wbox.maxExtents.z < testBox.maxExtents.z)
coverage = (wbox.maxExtents.z - testBox.minExtents.z) / (testBox.maxExtents.z - testBox.minExtents.z);
else
coverage = 1.0f;
}
return coverage;
}
F32 WaterHexagon::getSurfaceHeight( const Point2F &pos ) const
{
if ( !mWorldBox.isContained( pos ) )
return -1.0f;
return getPosition().z;
}
void WaterHexagon::_getWaterPlane( const Point3F &camPos, PlaneF &outPlane, Point3F &outPos )
{
outPos = getPosition();
if ( mReflectNormalUp )
outPlane.set( outPos, Point3F(0,0,1) );
else
{
Point3F normal;
getRenderTransform().getColumn( 2, &normal );
outPlane.set( outPos, normal );
}
}
F32 WaterHexagon::distanceTo( const Point3F& point ) const
{
Box3F waterBox = getWorldBox();
waterBox.maxExtents.z = getPosition().z;
return waterBox.getDistanceToPoint( point );
}
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _WaterHexagon_H_
#define _WaterHexagon_H_
#ifndef _GAMEBASE_H_
#include "T3D/gameBase/gameBase.h"
#endif
#ifndef _GFXDEVICE_H_
#include "gfx/gfxDevice.h"
#endif
#ifndef _SCENEDATA_H_
#include "materials/sceneData.h"
#endif
#ifndef _MATINSTANCE_H_
#include "materials/matInstance.h"
#endif
#ifndef _GFXPRIMITIVEBUFFER_H_
#include "gfx/gfxPrimitiveBuffer.h"
#endif
#ifndef _RENDERPASSMANAGER_H_
#include "renderInstance/renderPassManager.h"
#endif
#ifndef _WATEROBJECT_H_
#include "environment/waterObject.h"
#endif
//*****************************************************************************
// WaterHexagon
//*****************************************************************************
class WaterHexagon : public WaterObject
{
typedef WaterObject Parent;
public:
// LEGACY support
enum EWaterType
{
eWater = 0,
eOceanWater = 1,
eRiverWater = 2,
eStagnantWater = 3,
eLava = 4,
eHotLava = 5,
eCrustyLava = 6,
eQuicksand = 7,
};
private:
enum MaskBits {
UpdateMask = Parent::NextFreeMask,
NextFreeMask = Parent::NextFreeMask << 1
};
// vertex / index buffers
Vector< GFXVertexBufferHandle<GFXWaterVertex>* > mVertBuffList;
Vector<GFXPrimitiveBufferHandle*> mPrimBuffList;
GFXVertexBufferHandle<GFXVertexPC> mRadialVertBuff;
GFXPrimitiveBufferHandle mRadialPrimBuff;
// misc
F32 mGridElementSize;
U32 mWidth;
U32 mHeight;
F32 mElapsedTime;
GFXTexHandle mBumpTex;
bool mGenerateVB;
// reflect plane
//ReflectPlane mReflectPlane;
//Point3F mReflectPlaneWorldPos;
GFXTexHandle mReflectTex;
// Stateblocks
GFXStateBlockRef mUnderwaterSB;
void setupVertexBlock( U32 width, U32 height, U32 rowOffset );
void setupPrimitiveBlock( U32 width, U32 height );
void setMultiPassProjection();
void clearVertBuffers();
static bool setGridSizeProperty( void *object, const char *index, const char *data );
protected:
//-------------------------------------------------------
// Standard engine functions
//-------------------------------------------------------
bool onAdd();
void onRemove();
U32 packUpdate (NetConnection *conn, U32 mask, BitStream *stream);
void unpackUpdate(NetConnection *conn, BitStream *stream);
bool castRay(const Point3F &start, const Point3F &end, RayInfo* info);
public:
WaterHexagon();
virtual ~WaterHexagon();
DECLARE_CONOBJECT(WaterHexagon);
static void initPersistFields();
void onStaticModified( const char* slotName, const char*newValue = NULL );
virtual void inspectPostApply();
virtual void setTransform( const MatrixF & mat );
virtual void setScale( const Point3F &scale );
// WaterObject
virtual F32 getWaterCoverage( const Box3F &worldBox ) const;
virtual F32 getSurfaceHeight( const Point2F &pos ) const;
virtual bool isUnderwater( const Point3F &pnt ) const;
// WaterHexagon
bool isPointSubmerged ( const Point3F &pos, bool worldSpace = true ) const{ return true; }
// SceneObject.
virtual F32 distanceTo( const Point3F& pos ) const;
protected:
// WaterObject
virtual void setShaderParams( SceneRenderState *state, BaseMatInstance *mat, const WaterMatParams &paramHandles );
virtual SceneData setupSceneGraphInfo( SceneRenderState *state );
virtual void setupVBIB();
virtual void innerRender( SceneRenderState *state );
virtual void _getWaterPlane( const Point3F &camPos, PlaneF &outPlane, Point3F &outPos );
};
#endif // _WaterHexagon_H_
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment