DYTSrouce/Tool/osgOcean/include/osgOcean/FFTOceanSurface
2024-11-22 23:19:31 +08:00

188 lines
6.7 KiB
Plaintext

/*
* This source file is part of the osgOcean library
*
* Copyright (C) 2009 Kim Bale
* Copyright (C) 2009 The University of Hull, UK
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3 of the License, or (at your option) any later
* version.
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
* http://www.gnu.org/copyleft/lesser.txt.
*/
#pragma once
#include <osgOcean/Export>
#include <osgOcean/FFTOceanTechnique>
#include <osgOcean/MipmapGeometry>
#include <osgOcean/OceanTile>
#include <osg/Timer>
#include <osg/NodeCallback>
#include <osgUtil/CullVisitor>
#include <osg/Program>
namespace osgOcean
{
/**
* Creates and manages the ocean surface geometry and rendering.
* Uses a modified geomipmapping algorithm to provide level of detail.
* LOD is managed automatically within the update and cull traversals.
*/
class OSGOCEAN_EXPORT FFTOceanSurface : public FFTOceanTechnique
{
private:
unsigned int _totalPoints; /**< Total number of points on width/height. */
unsigned int _numVertices; /**< Total number of vertices in array. */
unsigned int _newNumVertices; /**< Number of vertices after updateMipmaps is called */
osg::ref_ptr<osg::Vec3Array> _activeVertices; /**< Active vertex buffer. */
osg::ref_ptr<osg::Vec3Array> _activeNormals; /**< Active normal buffer. */
std::vector< std::vector<OceanTile> > _mipmapData; /**< Wave tile data. */
std::vector< std::vector< osg::ref_ptr<MipmapGeometry> > > _mipmapGeom; /**< Geometry tiles. */
public:
FFTOceanSurface(unsigned int FFTGridSize = 64,
unsigned int resolution = 256,
unsigned int numTiles = 17,
const osg::Vec2f& windDirection = osg::Vec2f(1.1f, 1.1f),
float windSpeed = 12.f,
float depth = 1000.f,
float reflectionDamping = 0.35f,
float waveScale = 1e-8f,
bool isChoppy = true,
float choppyFactor = -2.5f,
float animLoopTime = 10.f,
unsigned int numFrames = 256 );
FFTOceanSurface( const FFTOceanSurface& copy,
const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY );
virtual const char* libraryName() const { return "osgOcean"; }
virtual const char* className() const { return "FFTOceanSurface"; }
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const FFTOceanSurface*>(obj) != 0; }
protected:
~FFTOceanSurface(void);
public:
float getSurfaceHeightAt(float x, float y, osg::Vec3f* normal = NULL);
/**
* Checks for mipmap or frame changes and updates the geometry accordingly.
* Will rebuild state or geometry if found to be dirty.
*/
void update( unsigned int frame, const double& dt, const osg::Vec3f& eye );
/**
* Sets up geometry and mipmaping data.
* Forces stateset rebuid.
*/
void build( void );
private:
/**
* Creates ocean surface stateset.
* Loads shaders and adds uniforms and textures;
*/
void initStateSet( void );
/**
* Computes the ocean FFTs and stores vertices/normals for mipmap levels.
*/
void computeSea( unsigned int totalFrames );
/**
* Sets up with the ocean surface with mipmap geometry.
*/
void createOceanTiles( void );
/**
* Computes and assigns mipmap primitives to the geometry.
*/
void computePrimitives( void );
/**
* Copies vertices needs for the tiles into _activeVertices array.
*/
void computeVertices( unsigned int frame );
/**
* Checks for any changes in mipmap resolution based on eye position.
* @return true if any updates have occured.
*/
bool updateMipmaps( const osg::Vec3f& eye, unsigned int frame );
/**
* Adds primitives for main body of vertices.
*/
void addMainBody( MipmapGeometry* cTile );
/**
* Adds primitives for the right skirt.
*/
void addRightBorder ( MipmapGeometry* cTile, MipmapGeometry* xTile );
/**
* Adds primitives for the bottom skirt.
*/
void addBottomBorder( MipmapGeometry* cTile, MipmapGeometry* yTile );
/**
* Adds primitives for the corner piece.
*/
void addCornerPatch( MipmapGeometry* cTile, MipmapGeometry* xTile, MipmapGeometry* yTile, MipmapGeometry* xyTile );
/**
* Adds primitives for main body of the lowest resolution tile (2x2 vertices).
* This is a special case treated similar to a corner piece.
*/
void addMaxDistMainBody( MipmapGeometry* cTile, MipmapGeometry* xTile, MipmapGeometry* yTile, MipmapGeometry* xyTile );
/**
* Adds primitives for edge of the lowest resolution tile (2x2 vertices).
*/
void addMaxDistEdge( MipmapGeometry* cTile, MipmapGeometry* xTile, MipmapGeometry* yTile );
/**
* Compute noise coordinates for the fragment shader.
* @param noiseSize Size of noise tile (m).
* @param movement Number of tiles moved x,y.
* @param speed Speed of movement(m/s).
* @parem time Simulation Time.
*/
osg::Vec3f computeNoiseCoords(float noiseSize, const osg::Vec2f& movement, float speed, float time);
/**
* Creates a custom DOT3 noise map for the ocean surface.
* This will execute an FFT to generate a height field from which the normal map is generated.
* Default behaviour is to create a normal map using the params from the ocean geometry setup.
*/
osg::ref_ptr<osg::Texture2D> createNoiseMap( unsigned int FFTSize,
const osg::Vec2f& windDir,
float windSpeed,
float waveScale,
float tileResolution );
/**
* Convenience method for retrieving mipmap geometry from _oceanGeom.
*/
inline MipmapGeometry* getTile( unsigned int x, unsigned int y ){
return _mipmapGeom.at(y).at(x).get();
}
/**
* Convenience method for loading the ocean shader.
* @return NULL if shader files were not found
*/
osg::Program* createShader(void);
};
}// namespace