tge/engine/dgl/gVectorField.h
2017-04-17 06:17:10 -06:00

150 lines
5.0 KiB
C++
Executable File

//------------------------------------------------------------------------------
// Vector Field
//------------------------------------------------------------------------------
#ifndef _GVECTORFIELD_H_
#define _GVECTORFIELD_H_
#include "math/mPoint.h"
#include "core/stream.h"
// Comment this line out to disable the ability to render out the field
#define ENABLE_FIELD_VISUALIZE
/// Function pointer that is used for functions to init vector fields
/// @note This function will be passed the normal texture coordinates in outVec
typedef void(FN_CDECL *VectorFieldInitFn)( const int x, const int y, const Point2I &resolution, const F32 maxX, const F32 maxY, Point2F *outVec );
class VectorField
{
private:
Point2I mFieldResolution; ///< Resolution of the vector field, x * y = number of quads
Point2F *mVectorField; ///< Vector Field
Point2F *mFieldVerts; ///< Vertices for rendering the field
U16 *mFieldIndices; ///< Indices for rendering the field
Point2F mMax; ///< Maximum texture coordinate values
#ifdef ENABLE_FIELD_VISUALIZE
Point2F *mUnflippedVecField; ///< If the coords get flipped, then this will be unflipped
#endif
/// Helper function to create the vector field
///
/// @param resolution Vector Field resolution
void allocVectorField( const Point2I &resolution );
/// Helper function to destroy the vector field
void destroyVectorField();
/// Helper function to null the pointers
void nullField();
/// Helper inline just so I can store the vector field as a 1d array but access
/// it as a 2d array
Point2F &getVector( const U32 x, const U32 y );
const Point2F &getVector( const U32 x, const U32 y ) const;
/// Put this field out to a stream
void serialize( Stream *stream ) const;
/// Read a stream and set up this field
void unserialize( Stream *stream );
public:
/// This is used to specify flip options for creating the texture coord array
enum TextureCoordFlip
{
Flip_None = 0,
Flip_X = BIT(0),
Flip_Y = BIT(1),
Flip_XY = Flip_X | Flip_Y
};
/// Default Constructor
VectorField();
/// Constructor
///
/// @param resolution Vector Field resolution
/// @param maxX Maximum value that can be assigned to an x-coord
/// @param maxY Maximum value that can be assigned to a y-coord
/// @param flip Flipping options for the texture coordinates
/// @param initFn Function pointer to init the vector field values with
VectorField( const Point2I &resolution, const F32 maxX = 1.f, const F32 maxY = 1.f,
TextureCoordFlip flip = Flip_None, VectorFieldInitFn initFn = NULL );
/// Constructor with file name
///
/// @param fileName File name to load from
VectorField( const char *fileName );
/// Destructor
~VectorField();
/// Init the vector field
/// @param maxX Maximum value that can be assigned to an x-coord
/// @param maxY Maximum value that can be assigned to a y-coord
/// @param flip Flipping options for the texture coordinates
/// @param initFn Function pointer to init the vector field values with
void initVectorField( F32 maxX = 1.f, F32 maxY = 1.f, TextureCoordFlip flip = Flip_None, VectorFieldInitFn initFn = NULL );
/// Load the vector field from a file
/// @see saveField
///
/// @param fileName File name to load from
bool loadField( const char *fileName );
/// Save the vector field to a file
///
/// @param fileName File name to save to
bool saveField( const char *fileName ) const;
/// Render out the vector field
///
/// @param texture True if this should enable texturing
void renderField( bool texture = false ) const;
/// Render the field to let someone visualize what it is doing
void visualizeField( F32 alpha = 1.f ) const;
};
//------------------------------------------------------------------------------
inline Point2F &VectorField::getVector( const U32 x, const U32 y )
{
AssertFatal( x < mFieldResolution.x && y < mFieldResolution.y, "Vector Field access out of bounds" );
return mVectorField[x + y * mFieldResolution.x];
}
inline const Point2F &VectorField::getVector( const U32 x, const U32 y ) const
{
AssertFatal( x < mFieldResolution.x && y < mFieldResolution.y, "Vector Field access out of bounds" );
return mVectorField[x + y * mFieldResolution.x];
}
//------------------------------------------------------------------------------
#ifndef ENABLE_FIELD_VISUALIZE
inline void VectorField::visualizeField( F32 alpha /* = 0.5f */ ) const
{
}
#endif
//------------------------------------------------------------------------------
inline void VectorField::nullField()
{
#ifdef ENABLE_FIELD_VISUALIZE
mUnflippedVecField = NULL;
#endif
mFieldVerts = NULL;
mFieldIndices = NULL;
mVectorField = NULL;
}
#endif