[Python-ogre-commit] SF.net SVN: python-ogre: [579] trunk/python-ogre
Brought to you by:
andy_miller,
roman_yakovenko
From: <and...@us...> - 2008-03-09 11:11:25
|
Revision: 579 http://python-ogre.svn.sourceforge.net/python-ogre/?rev=579&view=rev Author: andy_miller Date: 2008-03-09 04:11:30 -0700 (Sun, 09 Mar 2008) Log Message: ----------- Updates for 1.2 RC2 Modified Paths: -------------- trunk/python-ogre/PythonOgreConfig_nt.py trunk/python-ogre/ThirdParty/caelum/Astronomy.cpp trunk/python-ogre/ThirdParty/caelum/Astronomy.h trunk/python-ogre/ThirdParty/caelum/CaelumPrerequisites.h trunk/python-ogre/ThirdParty/caelum/GroundFog.cpp trunk/python-ogre/ThirdParty/caelum/GroundFog.h trunk/python-ogre/ThirdParty/caelum/ImageHelper.cpp trunk/python-ogre/ThirdParty/caelum/ImageHelper.h trunk/python-ogre/ThirdParty/caelum/SolarSystemModel.h trunk/python-ogre/ThirdParty/forests/BatchPage.cpp trunk/python-ogre/ThirdParty/forests/BatchPage.h trunk/python-ogre/ThirdParty/forests/BatchedGeometry.cpp trunk/python-ogre/ThirdParty/forests/BatchedGeometry.h trunk/python-ogre/ThirdParty/forests/GrassLoader.cpp trunk/python-ogre/ThirdParty/forests/GrassLoader.h trunk/python-ogre/ThirdParty/forests/ImpostorPage.cpp trunk/python-ogre/ThirdParty/forests/ImpostorPage.h trunk/python-ogre/ThirdParty/forests/PagedGeometry.cpp trunk/python-ogre/ThirdParty/forests/PagedGeometry.h trunk/python-ogre/ThirdParty/forests/PropertyMaps.cpp trunk/python-ogre/ThirdParty/forests/PropertyMaps.h trunk/python-ogre/ThirdParty/forests/StaticBillboardSet.cpp trunk/python-ogre/ThirdParty/forests/StaticBillboardSet.h trunk/python-ogre/ThirdParty/forests/TreeLoader2D.cpp trunk/python-ogre/ThirdParty/forests/TreeLoader2D.h trunk/python-ogre/ThirdParty/forests/TreeLoader3D.cpp trunk/python-ogre/ThirdParty/forests/TreeLoader3D.h trunk/python-ogre/ThirdParty/quickgui/QuickGUIComboBox.cpp trunk/python-ogre/ThirdParty/quickgui/QuickGUIExportDLL.h trunk/python-ogre/ThirdParty/quickgui/QuickGUILabel.cpp trunk/python-ogre/ThirdParty/quickgui/QuickGUIManager.h trunk/python-ogre/ThirdParty/quickgui/QuickGUIPanel.cpp trunk/python-ogre/ThirdParty/quickgui/QuickGUIPanel.h trunk/python-ogre/ThirdParty/quickgui/QuickGUIQuad.cpp trunk/python-ogre/ThirdParty/quickgui/QuickGUIQuad.h trunk/python-ogre/ThirdParty/quickgui/QuickGUIQuadContainer.cpp trunk/python-ogre/ThirdParty/quickgui/QuickGUISheet.cpp trunk/python-ogre/ThirdParty/quickgui/QuickGUISheet.h trunk/python-ogre/ThirdParty/quickgui/QuickGUISkinSet.cpp trunk/python-ogre/ThirdParty/quickgui/QuickGUIText.cpp trunk/python-ogre/ThirdParty/quickgui/QuickGUITextBox.cpp trunk/python-ogre/ThirdParty/quickgui/QuickGUITextHelper.cpp trunk/python-ogre/ThirdParty/quickgui/QuickGUITextHelper.h trunk/python-ogre/ThirdParty/quickgui/QuickGUITitleBar.cpp trunk/python-ogre/ThirdParty/quickgui/QuickGUIWidget.cpp trunk/python-ogre/ThirdParty/quickgui/QuickGUIWidget.h trunk/python-ogre/ThirdParty/quickgui/QuickGUIWindow.cpp trunk/python-ogre/ThirdParty/quickgui/QuickGUIWindow.h trunk/python-ogre/code_generators/cegui/generate_code.py trunk/python-ogre/code_generators/common_utils/__init__.py trunk/python-ogre/code_generators/nxogre_09/hand_made_wrappers.py trunk/python-ogre/code_generators/ogre/generate_code.py trunk/python-ogre/code_generators/ogre/python_ogre_sizeof.h trunk/python-ogre/code_generators/ogreforests/generate_code.py trunk/python-ogre/code_generators/ogreforests/hand_made_wrappers.py trunk/python-ogre/code_generators/ogreforests/python_forests.h trunk/python-ogre/code_generators/ogreforests/python_forests_aliases.h trunk/python-ogre/code_generators/ogreforests/python_forests_sizeof.h trunk/python-ogre/code_generators/ogrerefapp/hand_made_wrappers.py trunk/python-ogre/code_generators/particleuniverse/generate_code.py trunk/python-ogre/code_generators/particleuniverse/python_particleuniverse_aliases.h trunk/python-ogre/code_generators/particleuniverse/python_particleuniverse_sizeof.h trunk/python-ogre/code_generators/plib/generate_code.py trunk/python-ogre/code_generators/quickgui/generate_code.py trunk/python-ogre/code_generators/theora/customization_data.py trunk/python-ogre/code_generators/theora/generate_code.py trunk/python-ogre/code_generators/theora/python_theora.h trunk/python-ogre/code_generators/theora/python_theora_aliases.h trunk/python-ogre/demos/navi/Demo_navi.py trunk/python-ogre/demos/navi/Media/NaviDemo.material trunk/python-ogre/demos/navi/Media/cerulean.jpg trunk/python-ogre/demos/navi/resources.cfg trunk/python-ogre/demos/ogreal/Demo_RenderToTexture.py trunk/python-ogre/demos/theora/demo_video.py trunk/python-ogre/environment.py trunk/python-ogre/packages_2.5/ogre/renderer/OGRE/sf_OIS.py Modified: trunk/python-ogre/PythonOgreConfig_nt.py =================================================================== --- trunk/python-ogre/PythonOgreConfig_nt.py 2008-02-24 08:05:30 UTC (rev 578) +++ trunk/python-ogre/PythonOgreConfig_nt.py 2008-03-09 11:11:30 UTC (rev 579) @@ -66,7 +66,7 @@ PATH_PhysX= "c:/program files/AGEIA Technologies/SDK/v2.7.3/SDKs" PATH_Theora= os.path.join(PATH_OgreAddons,'videoplugin','TheoraVideo') PATH_ffmpeg= os.path.join(PATH_THIRDPARTY,'extra') -PATH_navi = os.path.join(BASE_DIR, 'navi','Navi') +PATH_navi = os.path.join(BASE_DIR, 'navi', 'navi') PATH_particleuniverse = os.path.join(PATH_Ogre, 'PlugIns', 'ParticleUniverse' ) Modified: trunk/python-ogre/ThirdParty/caelum/Astronomy.cpp =================================================================== --- trunk/python-ogre/ThirdParty/caelum/Astronomy.cpp 2008-02-24 08:05:30 UTC (rev 578) +++ trunk/python-ogre/ThirdParty/caelum/Astronomy.cpp 2008-03-09 11:11:30 UTC (rev 579) @@ -225,7 +225,7 @@ ::_controlfp (oldMode, _MCW_PC); } #else - void Astronomy::enterHighPrecissionFloatingPointMode () + int Astronomy::enterHighPrecissionFloatingPointMode () { // Meaningless return 0xC0FFEE; Modified: trunk/python-ogre/ThirdParty/caelum/Astronomy.h =================================================================== --- trunk/python-ogre/ThirdParty/caelum/Astronomy.h 2008-02-24 08:05:30 UTC (rev 578) +++ trunk/python-ogre/ThirdParty/caelum/Astronomy.h 2008-03-09 11:11:30 UTC (rev 579) @@ -151,4 +151,4 @@ }; } -#endif // SOLARSYSTEMMODEL_H \ No newline at end of file +#endif // SOLARSYSTEMMODEL_H Modified: trunk/python-ogre/ThirdParty/caelum/CaelumPrerequisites.h =================================================================== --- trunk/python-ogre/ThirdParty/caelum/CaelumPrerequisites.h 2008-02-24 08:05:30 UTC (rev 578) +++ trunk/python-ogre/ThirdParty/caelum/CaelumPrerequisites.h 2008-03-09 11:11:30 UTC (rev 579) @@ -24,20 +24,20 @@ // Include external headers #include "Ogre.h" -// Define the dll export qualifier if compiling for Windows -// // #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 -// // #ifdef CAELUM_LIB -// // #define DllExport __declspec (dllexport) -// // #else -// // #ifdef __MINGW32__ -// // #define DllExport -// // #else -// // #define DllExport __declspec (dllimport) -// // #endif -// // #endif -// // #else +// // Define the dll export qualifier if compiling for Windows +// #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 +// #ifdef CAELUM_LIB +// #define DllExport __declspec (dllexport) +// #else +// #ifdef __MINGW32__ +// #define DllExport +// #else +// #define DllExport __declspec (dllimport) +// #endif +// #endif +// #else #define DllExport -// // #endif +// #endif // Define the version code #define CAELUM_VERSION_MAIN 0 Modified: trunk/python-ogre/ThirdParty/caelum/GroundFog.cpp =================================================================== --- trunk/python-ogre/ThirdParty/caelum/GroundFog.cpp 2008-02-24 08:05:30 UTC (rev 578) +++ trunk/python-ogre/ThirdParty/caelum/GroundFog.cpp 2008-03-09 11:11:30 UTC (rev 579) @@ -198,4 +198,4 @@ params->setNamedConstant("fogVerticalDecay", getVerticalDecay()); params->setNamedConstant("fogGroundLevel", getGroundLevel()); } -} \ No newline at end of file +} Modified: trunk/python-ogre/ThirdParty/caelum/GroundFog.h =================================================================== --- trunk/python-ogre/ThirdParty/caelum/GroundFog.h 2008-02-24 08:05:30 UTC (rev 578) +++ trunk/python-ogre/ThirdParty/caelum/GroundFog.h 2008-03-09 11:11:30 UTC (rev 579) @@ -149,4 +149,4 @@ } -#endif //GROUNDFOG_H \ No newline at end of file +#endif //GROUNDFOG_H Modified: trunk/python-ogre/ThirdParty/caelum/ImageHelper.cpp =================================================================== --- trunk/python-ogre/ThirdParty/caelum/ImageHelper.cpp 2008-02-24 08:05:30 UTC (rev 578) +++ trunk/python-ogre/ThirdParty/caelum/ImageHelper.cpp 2008-03-09 11:11:30 UTC (rev 579) @@ -64,5 +64,4 @@ return cf; } - -} \ No newline at end of file +} Modified: trunk/python-ogre/ThirdParty/caelum/ImageHelper.h =================================================================== --- trunk/python-ogre/ThirdParty/caelum/ImageHelper.h 2008-02-24 08:05:30 UTC (rev 578) +++ trunk/python-ogre/ThirdParty/caelum/ImageHelper.h 2008-03-09 11:11:30 UTC (rev 579) @@ -41,4 +41,4 @@ bool wrapX = true); } -#endif // CAELUM_HEADER__IMAGE_HELPER_H \ No newline at end of file +#endif // CAELUM_HEADER__IMAGE_HELPER_H Modified: trunk/python-ogre/ThirdParty/caelum/SolarSystemModel.h =================================================================== --- trunk/python-ogre/ThirdParty/caelum/SolarSystemModel.h 2008-02-24 08:05:30 UTC (rev 578) +++ trunk/python-ogre/ThirdParty/caelum/SolarSystemModel.h 2008-03-09 11:11:30 UTC (rev 579) @@ -61,4 +61,4 @@ }; } -#endif // SOLARSYSTEMMODEL_H \ No newline at end of file +#endif // SOLARSYSTEMMODEL_H Modified: trunk/python-ogre/ThirdParty/forests/BatchPage.cpp =================================================================== --- trunk/python-ogre/ThirdParty/forests/BatchPage.cpp 2008-02-24 08:05:30 UTC (rev 578) +++ trunk/python-ogre/ThirdParty/forests/BatchPage.cpp 2008-03-09 11:11:30 UTC (rev 579) @@ -15,17 +15,18 @@ #include "BatchPage.h" #include "BatchedGeometry.h" -#include "OgreRoot.h" -#include "OgreCamera.h" -#include "OgreVector3.h" -#include "OgreQuaternion.h" -#include "OgreEntity.h" -#include "OgreRenderSystem.h" -#include "OgreRenderSystemCapabilities.h" -#include "OgreHighLevelGpuProgram.h" -#include "OgreHighLevelGpuProgramManager.h" +#include <OgreRoot.h> +#include <OgreCamera.h> +#include <OgreVector3.h> +#include <OgreQuaternion.h> +#include <OgreEntity.h> +#include <OgreRenderSystem.h> +#include <OgreRenderSystemCapabilities.h> +#include <OgreHighLevelGpuProgram.h> +#include <OgreHighLevelGpuProgramManager.h> using namespace Ogre; +namespace PagedGeometry { //------------------------------------------------------------------------------------- @@ -115,13 +116,13 @@ if (fadeEnabled != enabled){ fadeEnabled = enabled; - if (enabled) { +// if (enabled) { //Transparent batches should render after impostors batch->setRenderQueueGroup(RENDER_QUEUE_6); - } else { - //Opaque batches should render in the normal render queue - batch->setRenderQueueGroup(RENDER_QUEUE_MAIN); - } +// } else { +// //Opaque batches should render in the normal render queue +// batch->setRenderQueueGroup(RENDER_QUEUE_MAIN); +// } this->visibleDist = visibleDist; this->invisibleDist = invisibleDist; @@ -134,7 +135,7 @@ if (!shadersSupported) return; - unsigned int i = 0; + uint32 i = 0; BatchedGeometry::SubBatchIterator it = batch->getSubBatchIterator(); while (it.hasMoreElements()){ BatchedGeometry::SubBatch *subBatch = it.getNext(); @@ -270,3 +271,4 @@ } } +} Modified: trunk/python-ogre/ThirdParty/forests/BatchPage.h =================================================================== --- trunk/python-ogre/ThirdParty/forests/BatchPage.h 2008-02-24 08:05:30 UTC (rev 578) +++ trunk/python-ogre/ThirdParty/forests/BatchPage.h 2008-03-09 11:11:30 UTC (rev 579) @@ -18,9 +18,10 @@ #include "PagedGeometry.h" #include "BatchedGeometry.h" -#include "OgrePrerequisites.h" -#include "OgreStringConverter.h" +#include <OgrePrerequisites.h> +#include <OgreStringConverter.h> +namespace PagedGeometry { /** \brief The BatchPage class renders entities as StaticGeometry. @@ -74,5 +75,6 @@ } }; +} #endif Modified: trunk/python-ogre/ThirdParty/forests/BatchedGeometry.cpp =================================================================== --- trunk/python-ogre/ThirdParty/forests/BatchedGeometry.cpp 2008-02-24 08:05:30 UTC (rev 578) +++ trunk/python-ogre/ThirdParty/forests/BatchedGeometry.cpp 2008-03-09 11:11:30 UTC (rev 579) @@ -15,25 +15,26 @@ #include "BatchedGeometry.h" -#include "OgreRoot.h" -#include "OgreRenderSystem.h" -#include "OgreCamera.h" -#include "OgreVector3.h" -#include "OgreQuaternion.h" -#include "OgreSceneNode.h" -#include "OgreString.h" -#include "OgreStringConverter.h" -#include "OgreEntity.h" -#include "OgreSubMesh.h" -#include "OgreSubEntity.h" -#include "OgreMesh.h" -#include "OgreMeshManager.h" -#include "OgreHardwareBufferManager.h" -#include "OgreHardwareBuffer.h" -#include "OgreMaterialManager.h" -#include "OgreMaterial.h" +#include <OgreRoot.h> +#include <OgreRenderSystem.h> +#include <OgreCamera.h> +#include <OgreVector3.h> +#include <OgreQuaternion.h> +#include <OgreSceneNode.h> +#include <OgreString.h> +#include <OgreStringConverter.h> +#include <OgreEntity.h> +#include <OgreSubMesh.h> +#include <OgreSubEntity.h> +#include <OgreMesh.h> +#include <OgreMeshManager.h> +#include <OgreHardwareBufferManager.h> +#include <OgreHardwareBuffer.h> +#include <OgreMaterialManager.h> +#include <OgreMaterial.h> using namespace Ogre; +namespace PagedGeometry { //------------------------------------------------------------------------------------- @@ -56,15 +57,19 @@ void BatchedGeometry::addEntity(Entity *ent, const Vector3 &position, const Quaternion &orientation, const Vector3 &scale, const Ogre::ColourValue &color) { + MeshPtr mesh = ent->getMesh(); + if (mesh->sharedVertexData != NULL) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Shared vertex data not allowed", "BatchedGeometry::addEntity()"); + //For each subentity - for (uint i = 0; i < ent->getNumSubEntities(); ++i){ + for (uint32 i = 0; i < ent->getNumSubEntities(); ++i){ //Get the subentity SubEntity *subEntity = ent->getSubEntity(i); SubMesh *subMesh = subEntity->getSubMesh(); //Generate a format string that uniquely identifies this material & vertex/index format if (subMesh->vertexData == NULL) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "BatchedGeometry cannot use meshes with shared vertex data", "BatchedGeometry::addEntity()"); + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "SubMesh vertex data not found!", "BatchedGeometry::addEntity()"); String formatStr = getFormatString(subEntity); //If a batch using an identical format exists... @@ -234,7 +239,15 @@ built = false; Material *origMat = ((MaterialPtr)MaterialManager::getSingleton().getByName(ent->getMaterialName())).getPointer(); + if (origMat) { material = MaterialManager::getSingleton().getByName(getMaterialClone(origMat)->getName()); + } else { + MaterialManager::ResourceCreateOrRetrieveResult result = MaterialManager::getSingleton().createOrRetrieve("PagedGeometry_Batched_Material", "General"); + if (result.first.isNull()) { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "BatchedGeometry failed to create a material for entity with invalid material.", "BatchedGeometry::SubBatch::SubBatch(BatchedGeometry *parent, SubEntity *ent)"); + } + material = result.first; + } //Setup vertex/index data structure vertexData = meshType->vertexData->clone(false); @@ -651,4 +664,6 @@ return parent->queryLights(); } +} + #endif Modified: trunk/python-ogre/ThirdParty/forests/BatchedGeometry.h =================================================================== --- trunk/python-ogre/ThirdParty/forests/BatchedGeometry.h 2008-02-24 08:05:30 UTC (rev 578) +++ trunk/python-ogre/ThirdParty/forests/BatchedGeometry.h 2008-03-09 11:11:30 UTC (rev 579) @@ -16,11 +16,12 @@ #ifndef __BatchedGeometry_H__ #define __BatchedGeometry_H__ -#include "OgrePrerequisites.h" -#include "OgreMovableObject.h" -#include "OgreSceneNode.h" -#include "OgreMaterialManager.h" +#include <OgrePrerequisites.h> +#include <OgreMovableObject.h> +#include <OgreSceneNode.h> +#include <OgreMaterialManager.h> +namespace PagedGeometry { class BatchedGeometry: public Ogre::MovableObject { @@ -129,6 +130,6 @@ }; +} - #endif \ No newline at end of file Modified: trunk/python-ogre/ThirdParty/forests/GrassLoader.cpp =================================================================== --- trunk/python-ogre/ThirdParty/forests/GrassLoader.cpp 2008-02-24 08:05:30 UTC (rev 578) +++ trunk/python-ogre/ThirdParty/forests/GrassLoader.cpp 2008-03-09 11:11:30 UTC (rev 579) @@ -1,5 +1,6 @@ /*------------------------------------------------------------------------------------- Copyright (c) 2006 John Judnich +Modified 2008 by Erik Hjortsberg (eri...@it...) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: @@ -12,637 +13,34 @@ #include "PagedGeometry.h" #include "PropertyMaps.h" -#include "OgreRoot.h" -#include "OgreTimer.h" -#include "OgreCamera.h" -#include "OgreVector3.h" -#include "OgreQuaternion.h" -#include "OgreEntity.h" -#include "OgreString.h" -#include "OgreStringConverter.h" -#include "OgreMaterialManager.h" -#include "OgreMaterial.h" -#include "OgreHardwareBufferManager.h" -#include "OgreHardwareBuffer.h" -#include "OgreMeshManager.h" -#include "OgreMesh.h" -#include "OgreSubMesh.h" -#include "OgreLogManager.h" -#include "OgreTextureManager.h" -#include "OgreHardwarePixelBuffer.h" -#include "OgreRenderSystem.h" -#include "OgreRenderSystemCapabilities.h" -#include "OgreHighLevelGpuProgram.h" -#include "OgreHighLevelGpuProgramManager.h" +#include <OgreRoot.h> +#include <OgreTimer.h> +#include <OgreCamera.h> +#include <OgreVector3.h> +#include <OgreQuaternion.h> +#include <OgreEntity.h> +#include <OgreString.h> +#include <OgreStringConverter.h> +#include <OgreMaterialManager.h> +#include <OgreMaterial.h> +#include <OgreHardwareBufferManager.h> +#include <OgreHardwareBuffer.h> +#include <OgreMeshManager.h> +#include <OgreMesh.h> +#include <OgreSubMesh.h> +#include <OgreLogManager.h> +#include <OgreTextureManager.h> +#include <OgreHardwarePixelBuffer.h> +#include <OgreRenderSystem.h> +#include <OgreRenderSystemCapabilities.h> +#include <OgreHighLevelGpuProgram.h> +#include <OgreHighLevelGpuProgramManager.h> using namespace Ogre; +namespace PagedGeometry { -unsigned long GrassLoader::GUID = 0; - -GrassLoader::GrassLoader(PagedGeometry *geom) +GrassLayer::GrassLayer(PagedGeometry *geom, GrassLoader<GrassLayer> *ldr) { - GrassLoader::geom = geom; - - heightFunction = NULL; - heightFunctionUserData = NULL; - - windDir = Vector3::UNIT_X; - densityFactor = 1.0f; - renderQueue = RENDER_QUEUE_6; - - windTimer.reset(); - lastTime = 0; -} - -GrassLoader::~GrassLoader() -{ - std::list<GrassLayer*>::iterator it; - for (it = layerList.begin(); it != layerList.end(); ++it){ - delete *it; - } - layerList.clear(); -} - -GrassLayer *GrassLoader::addLayer(const String &material) -{ - GrassLayer *layer = new GrassLayer(geom, this); - layer->setMaterialName(material); - layerList.push_back(layer); - - return layer; -} - -void GrassLoader::deleteLayer(GrassLayer *layer) -{ - layerList.remove(layer); - delete layer; -} - -void GrassLoader::frameUpdate() -{ - unsigned long currentTime = windTimer.getMilliseconds(); - unsigned long ellapsedTime = currentTime - lastTime; - lastTime = currentTime; - - float ellapsed = ellapsedTime / 1000.0f; - - //Update the vertex shader parameters - std::list<GrassLayer*>::iterator it; - for (it = layerList.begin(); it != layerList.end(); ++it){ - GrassLayer *layer = *it; - - layer->_updateShaders(); - - GpuProgramParametersSharedPtr params = layer->material->getTechnique(0)->getPass(0)->getVertexProgramParameters(); - if (layer->animate){ - //Increment animation frame - layer->waveCount += ellapsed * (layer->animSpeed * Math::PI); - if (layer->waveCount > Math::PI*2) layer->waveCount -= Math::PI*2; - - //Set vertex shader parameters - params->setNamedConstant("time", layer->waveCount); - params->setNamedConstant("frequency", layer->animFreq); - - Vector3 direction = windDir * layer->animMag; - params->setNamedConstant("direction", Vector4(direction.x, direction.y, direction.z, 0)); - - } - } -} - -void GrassLoader::loadPage(PageInfo &page) -{ - //Seed random number generator based on page indexes - uint16 xSeed = static_cast<uint16>(page.xIndex % 0xFFFF); - uint16 zSeed = static_cast<uint16>(page.zIndex % 0xFFFF); - uint32 seed = (xSeed << 16) | zSeed; - srand(seed); - - std::list<GrassLayer*>::iterator it; - for (it = layerList.begin(); it != layerList.end(); ++it){ - GrassLayer *layer = *it; - - //Calculate how much grass needs to be added - float volume = page.bounds.width() * page.bounds.height(); - unsigned int grassCount = layer->density * densityFactor * volume; - - //The vertex buffer can't be allocated until the exact number of polygons is known, - //so the locations of all grasses in this page must be precalculated. - - //Precompute grass locations into an array of floats. A plain array is used for speed; - //there's no need to use a dynamic sized array since a maximum size is known. - float *position = new float[grassCount*2]; - if (layer->densityMap){ - if (layer->densityMap->getFilter() == MAPFILTER_NONE) - grassCount = layer->_populateGrassList_UnfilteredDM(page, position, grassCount); - else if (layer->densityMap->getFilter() == MAPFILTER_BILINEAR) - grassCount = layer->_populateGrassList_BilinearDM(page, position, grassCount); - } else { - grassCount = layer->_populateGrassList_Uniform(page, position, grassCount); - } - - //Don't build a mesh unless it contains something - if (grassCount != 0){ - Mesh *mesh = NULL; - switch (layer->renderTechnique){ - case GRASSTECH_QUAD: - mesh = generateGrass_QUAD(page, layer, position, grassCount); - break; - case GRASSTECH_CROSSQUADS: - mesh = generateGrass_CROSSQUADS(page, layer, position, grassCount); - break; - case GRASSTECH_SPRITE: - mesh = generateGrass_SPRITE(page, layer, position, grassCount); - break; - } - assert(mesh); - - //Add the mesh to PagedGeometry - Entity *entity = geom->getCamera()->getSceneManager()->createEntity(getUniqueID(), mesh->getName()); - entity->setRenderQueueGroup(renderQueue); - entity->setCastShadows(false); - addEntity(entity, page.centerPoint, Quaternion::IDENTITY, Vector3::UNIT_SCALE); - geom->getSceneManager()->destroyEntity(entity); - - //Store the mesh pointer - page.userData = mesh; - } else { - //No mesh - page.userData = NULL; - } - - //Delete the position list - delete[] position; - } -} - -void GrassLoader::unloadPage(const PageInfo &page) -{ - //Unload mesh - Mesh *mesh = (Mesh*)page.userData; - if (mesh) - MeshManager::getSingleton().remove(mesh->getName()); -} - -Mesh *GrassLoader::generateGrass_QUAD(PageInfo &page, GrassLayer *layer, float *grassPositions, unsigned int grassCount) -{ - //Calculate the number of quads to be added - unsigned int quadCount; - quadCount = grassCount; - - //Create manual mesh to store grass quads - MeshPtr mesh = MeshManager::getSingleton().createManual(getUniqueID(), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - SubMesh *subMesh = mesh->createSubMesh(); - subMesh->useSharedVertices = false; - - //Setup vertex format information - subMesh->vertexData = new VertexData; - subMesh->vertexData->vertexStart = 0; - subMesh->vertexData->vertexCount = 4 * quadCount; - - VertexDeclaration* dcl = subMesh->vertexData->vertexDeclaration; - size_t offset = 0; - dcl->addElement(0, offset, VET_FLOAT3, VES_POSITION); - offset += VertexElement::getTypeSize(VET_FLOAT3); - dcl->addElement(0, offset, VET_COLOUR, VES_DIFFUSE); - offset += VertexElement::getTypeSize(VET_COLOUR); - dcl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES); - offset += VertexElement::getTypeSize(VET_FLOAT2); - - //Populate a new vertex buffer with grass - HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton() - .createVertexBuffer(offset, subMesh->vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); - float* pReal = static_cast<float*>(vbuf->lock(HardwareBuffer::HBL_DISCARD)); - - //Calculate size variance - float rndWidth = layer->maxWidth - layer->minWidth; - float rndHeight = layer->maxHeight - layer->minHeight; - - float minY = Math::POS_INFINITY, maxY = Math::NEG_INFINITY; - float *posPtr = grassPositions; //Position array "iterator" - for (uint16 i = 0; i < grassCount; ++i) - { - //Get the x and z positions from the position array - float x = *posPtr++; - float z = *posPtr++; - - //Get the color at the grass position - uint32 color; - if (layer->colorMap) - color = layer->colorMap->getColorAt(x, z); - else - color = 0xFFFFFFFF; - - //Calculate size - float rnd = Math::UnitRandom(); //The same rnd value is used for width and height to maintain aspect ratio - float halfScaleX = (layer->minWidth + rndWidth * rnd) * 0.5f; - float scaleY = (layer->minHeight + rndHeight * rnd); - - //Calculate rotation - float angle = Math::RangeRandom(0, Math::TWO_PI); - float xTrans = Math::Cos(angle) * halfScaleX; - float zTrans = Math::Sin(angle) * halfScaleX; - - //Calculate heights and edge positions - float x1 = x - xTrans, z1 = z - zTrans; - float x2 = x + xTrans, z2 = z + zTrans; - - float y1, y2; - if (heightFunction){ - y1 = heightFunction(x1, z1, heightFunctionUserData); - y2 = heightFunction(x2, z2, heightFunctionUserData); - } else { - y1 = 0; - y2 = 0; - } - - //Add vertices - *pReal++ = (x1 - page.centerPoint.x); *pReal++ = (y1 + scaleY); *pReal++ = (z1 - page.centerPoint.z); //pos - *((uint32*)pReal++) = color; //color - *pReal++ = 0; *pReal++ = 0; //uv - - *pReal++ = (x2 - page.centerPoint.x); *pReal++ = (y2 + scaleY); *pReal++ = (z2 - page.centerPoint.z); //pos - *((uint32*)pReal++) = color; //color - *pReal++ = 1; *pReal++ = 0; //uv - - *pReal++ = (x1 - page.centerPoint.x); *pReal++ = (y1); *pReal++ = (z1 - page.centerPoint.z); //pos - *((uint32*)pReal++) = color; //color - *pReal++ = 0; *pReal++ = 1; //uv - - *pReal++ = (x2 - page.centerPoint.x); *pReal++ = (y2); *pReal++ = (z2 - page.centerPoint.z); //pos - *((uint32*)pReal++) = color; //color - *pReal++ = 1; *pReal++ = 1; //uv - - //Update bounds - if (y1 < minY) minY = y1; - if (y2 < minY) minY = y2; - if (y1 + scaleY > maxY) maxY = y1 + scaleY; - if (y2 + scaleY > maxY) maxY = y2 + scaleY; - } - - vbuf->unlock(); - subMesh->vertexData->vertexBufferBinding->setBinding(0, vbuf); - - //Populate index buffer - subMesh->indexData->indexStart = 0; - subMesh->indexData->indexCount = 6 * quadCount; - subMesh->indexData->indexBuffer = HardwareBufferManager::getSingleton() - .createIndexBuffer(HardwareIndexBuffer::IT_16BIT, subMesh->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); - uint16* pI = static_cast<uint16*>(subMesh->indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD)); - for (uint16 i = 0; i < quadCount; ++i) - { - uint16 offset = i * 4; - - *pI++ = 0 + offset; - *pI++ = 2 + offset; - *pI++ = 1 + offset; - - *pI++ = 1 + offset; - *pI++ = 2 + offset; - *pI++ = 3 + offset; - } - - subMesh->indexData->indexBuffer->unlock(); - - //Finish up mesh - AxisAlignedBox bounds(page.bounds.left - page.centerPoint.x, minY, page.bounds.top - page.centerPoint.z, - page.bounds.right - page.centerPoint.x, maxY, page.bounds.bottom - page.centerPoint.z); - mesh->_setBounds(bounds); - Vector3 temp = bounds.getMaximum() - bounds.getMinimum(); - mesh->_setBoundingSphereRadius(temp.length() * 0.5f); - - LogManager::getSingleton().setLogDetail(static_cast<LoggingLevel>(0)); - mesh->load(); - LogManager::getSingleton().setLogDetail(LL_NORMAL); - - //Apply grass material to mesh - subMesh->setMaterialName(layer->material->getName()); - - //Return the mesh - return mesh.getPointer(); -} - -Mesh *GrassLoader::generateGrass_CROSSQUADS(PageInfo &page, GrassLayer *layer, float *grassPositions, unsigned int grassCount) -{ - //Calculate the number of quads to be added - unsigned int quadCount; - quadCount = grassCount * 2; - - //Create manual mesh to store grass quads - MeshPtr mesh = MeshManager::getSingleton().createManual(getUniqueID(), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - SubMesh *subMesh = mesh->createSubMesh(); - subMesh->useSharedVertices = false; - - //Setup vertex format information - subMesh->vertexData = new VertexData; - subMesh->vertexData->vertexStart = 0; - subMesh->vertexData->vertexCount = 4 * quadCount; - - VertexDeclaration* dcl = subMesh->vertexData->vertexDeclaration; - size_t offset = 0; - dcl->addElement(0, offset, VET_FLOAT3, VES_POSITION); - offset += VertexElement::getTypeSize(VET_FLOAT3); - dcl->addElement(0, offset, VET_COLOUR, VES_DIFFUSE); - offset += VertexElement::getTypeSize(VET_COLOUR); - dcl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES); - offset += VertexElement::getTypeSize(VET_FLOAT2); - - //Populate a new vertex buffer with grass - HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton() - .createVertexBuffer(offset, subMesh->vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); - float* pReal = static_cast<float*>(vbuf->lock(HardwareBuffer::HBL_DISCARD)); - - //Calculate size variance - float rndWidth = layer->maxWidth - layer->minWidth; - float rndHeight = layer->maxHeight - layer->minHeight; - - float minY = Math::POS_INFINITY, maxY = Math::NEG_INFINITY; - float *posPtr = grassPositions; //Position array "iterator" - for (uint16 i = 0; i < grassCount; ++i) - { - //Get the x and z positions from the position array - float x = *posPtr++; - float z = *posPtr++; - - //Get the color at the grass position - uint32 color; - if (layer->colorMap) - color = layer->colorMap->getColorAt(x, z); - else - color = 0xFFFFFFFF; - - //Calculate size - float rnd = Math::UnitRandom(); //The same rnd value is used for width and height to maintain aspect ratio - float halfScaleX = (layer->minWidth + rndWidth * rnd) * 0.5f; - float scaleY = (layer->minHeight + rndHeight * rnd); - - //Calculate rotation - float angle = Math::RangeRandom(0, Math::TWO_PI); - float xTrans = Math::Cos(angle) * halfScaleX; - float zTrans = Math::Sin(angle) * halfScaleX; - - //Calculate heights and edge positions - float x1 = x - xTrans, z1 = z - zTrans; - float x2 = x + xTrans, z2 = z + zTrans; - - float y1, y2; - if (heightFunction){ - y1 = heightFunction(x1, z1, heightFunctionUserData); - y2 = heightFunction(x2, z2, heightFunctionUserData); - } else { - y1 = 0; - y2 = 0; - } - - //Add vertices - *pReal++ = (x1 - page.centerPoint.x); *pReal++ = (y1 + scaleY); *pReal++ = (z1 - page.centerPoint.z); //pos - *((uint32*)pReal++) = color; //color - *pReal++ = 0; *pReal++ = 0; //uv - - *pReal++ = (x2 - page.centerPoint.x); *pReal++ = (y2 + scaleY); *pReal++ = (z2 - page.centerPoint.z); //pos - *((uint32*)pReal++) = color; //color - *pReal++ = 1; *pReal++ = 0; //uv - - *pReal++ = (x1 - page.centerPoint.x); *pReal++ = (y1); *pReal++ = (z1 - page.centerPoint.z); //pos - *((uint32*)pReal++) = color; //color - *pReal++ = 0; *pReal++ = 1; //uv - - *pReal++ = (x2 - page.centerPoint.x); *pReal++ = (y2); *pReal++ = (z2 - page.centerPoint.z); //pos - *((uint32*)pReal++) = color; //color - *pReal++ = 1; *pReal++ = 1; //uv - - //Update bounds - if (y1 < minY) minY = y1; - if (y2 < minY) minY = y2; - if (y1 + scaleY > maxY) maxY = y1 + scaleY; - if (y2 + scaleY > maxY) maxY = y2 + scaleY; - - //Calculate heights and edge positions - float x3 = x + zTrans, z3 = z - xTrans; - float x4 = x - zTrans, z4 = z + xTrans; - - float y3, y4; - if (heightFunction){ - y3 = heightFunction(x3, z3, heightFunctionUserData); - y4 = heightFunction(x4, z4, heightFunctionUserData); - } else { - y3 = 0; - y4 = 0; - } - - //Add vertices - *pReal++ = (x3 - page.centerPoint.x); *pReal++ = (y3 + scaleY); *pReal++ = (z3 - page.centerPoint.z); //pos - *((uint32*)pReal++) = color; //color - *pReal++ = 0; *pReal++ = 0; //uv - - *pReal++ = (x4 - page.centerPoint.x); *pReal++ = (y4 + scaleY); *pReal++ = (z4 - page.centerPoint.z); //pos - *((uint32*)pReal++) = color; //color - *pReal++ = 1; *pReal++ = 0; //uv - - *pReal++ = (x3 - page.centerPoint.x); *pReal++ = (y3); *pReal++ = (z3 - page.centerPoint.z); //pos - *((uint32*)pReal++) = color; //color - *pReal++ = 0; *pReal++ = 1; //uv - - *pReal++ = (x4 - page.centerPoint.x); *pReal++ = (y4); *pReal++ = (z4 - page.centerPoint.z); //pos - *((uint32*)pReal++) = color; //color - *pReal++ = 1; *pReal++ = 1; //uv - - //Update bounds - if (y3 < minY) minY = y1; - if (y4 < minY) minY = y2; - if (y3 + scaleY > maxY) maxY = y3 + scaleY; - if (y4 + scaleY > maxY) maxY = y4 + scaleY; - } - - vbuf->unlock(); - subMesh->vertexData->vertexBufferBinding->setBinding(0, vbuf); - - //Populate index buffer - subMesh->indexData->indexStart = 0; - subMesh->indexData->indexCount = 6 * quadCount; - subMesh->indexData->indexBuffer = HardwareBufferManager::getSingleton() - .createIndexBuffer(HardwareIndexBuffer::IT_16BIT, subMesh->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); - uint16* pI = static_cast<uint16*>(subMesh->indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD)); - for (uint16 i = 0; i < quadCount; ++i) - { - uint16 offset = i * 4; - - *pI++ = 0 + offset; - *pI++ = 2 + offset; - *pI++ = 1 + offset; - - *pI++ = 1 + offset; - *pI++ = 2 + offset; - *pI++ = 3 + offset; - } - - subMesh->indexData->indexBuffer->unlock(); - - //Finish up mesh - AxisAlignedBox bounds(page.bounds.left - page.centerPoint.x, minY, page.bounds.top - page.centerPoint.z, - page.bounds.right - page.centerPoint.x, maxY, page.bounds.bottom - page.centerPoint.z); - mesh->_setBounds(bounds); - Vector3 temp = bounds.getMaximum() - bounds.getMinimum(); - mesh->_setBoundingSphereRadius(temp.length() * 0.5f); - - LogManager::getSingleton().setLogDetail(static_cast<LoggingLevel>(0)); - mesh->load(); - LogManager::getSingleton().setLogDetail(LL_NORMAL); - - //Apply grass material to mesh - subMesh->setMaterialName(layer->material->getName()); - - //Return the mesh - return mesh.getPointer(); -} - -Mesh *GrassLoader::generateGrass_SPRITE(PageInfo &page, GrassLayer *layer, float *grassPositions, unsigned int grassCount) -{ - //Calculate the number of quads to be added - unsigned int quadCount; - quadCount = grassCount; - - //Create manual mesh to store grass quads - MeshPtr mesh = MeshManager::getSingleton().createManual(getUniqueID(), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - SubMesh *subMesh = mesh->createSubMesh(); - subMesh->useSharedVertices = false; - - //Setup vertex format information - subMesh->vertexData = new VertexData; - subMesh->vertexData->vertexStart = 0; - subMesh->vertexData->vertexCount = 4 * quadCount; - - VertexDeclaration* dcl = subMesh->vertexData->vertexDeclaration; - size_t offset = 0; - dcl->addElement(0, offset, VET_FLOAT3, VES_POSITION); - offset += VertexElement::getTypeSize(VET_FLOAT3); - dcl->addElement(0, offset, VET_FLOAT4, VES_NORMAL); - offset += VertexElement::getTypeSize(VET_FLOAT4); - dcl->addElement(0, offset, VET_COLOUR, VES_DIFFUSE); - offset += VertexElement::getTypeSize(VET_COLOUR); - dcl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES); - offset += VertexElement::getTypeSize(VET_FLOAT2); - - //Populate a new vertex buffer with grass - HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton() - .createVertexBuffer(offset, subMesh->vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); - float* pReal = static_cast<float*>(vbuf->lock(HardwareBuffer::HBL_DISCARD)); - - //Calculate size variance - float rndWidth = layer->maxWidth - layer->minWidth; - float rndHeight = layer->maxHeight - layer->minHeight; - - float minY = Math::POS_INFINITY, maxY = Math::NEG_INFINITY; - float *posPtr = grassPositions; //Position array "iterator" - for (uint16 i = 0; i < grassCount; ++i) - { - //Get the x and z positions from the position array - float x = *posPtr++; - float z = *posPtr++; - - //Calculate height - float y; - if (heightFunction){ - y = heightFunction(x, z, heightFunctionUserData); - } else { - y = 0; - } - - float x1 = (x - page.centerPoint.x); - float z1 = (z - page.centerPoint.z); - - //Get the color at the grass position - uint32 color; - if (layer->colorMap) - color = layer->colorMap->getColorAt(x, z); - else - color = 0xFFFFFFFF; - - //Calculate size - float rnd = Math::UnitRandom(); //The same rnd value is used for width and height to maintain aspect ratio - float halfXScale = (layer->minWidth + rndWidth * rnd) * 0.5f; - float scaleY = (layer->minHeight + rndHeight * rnd); - - //Randomly mirror grass textures - float uvLeft, uvRight; - if (Math::UnitRandom() > 0.5f){ - uvLeft = 0; - uvRight = 1; - } else { - uvLeft = 1; - uvRight = 0; - } - - //Add vertices - *pReal++ = x1; *pReal++ = y; *pReal++ = z1; //center position - *pReal++ = -halfXScale; *pReal++ = scaleY; *pReal++ = 0; *pReal++ = 0; //normal (used to store relative corner positions) - *((uint32*)pReal++) = color; //color - *pReal++ = uvLeft; *pReal++ = 0; //uv - - *pReal++ = x1; *pReal++ = y; *pReal++ = z1; //center position - *pReal++ = +halfXScale; *pReal++ = scaleY; *pReal++ = 0; *pReal++ = 0; //normal (used to store relative corner positions) - *((uint32*)pReal++) = color; //color - *pReal++ = uvRight; *pReal++ = 0; //uv - - *pReal++ = x1; *pReal++ = y; *pReal++ = z1; //center position - *pReal++ = -halfXScale; *pReal++ = 0.0f; *pReal++ = 0; *pReal++ = 0; //normal (used to store relative corner positions) - *((uint32*)pReal++) = color; //color - *pReal++ = uvLeft; *pReal++ = 1; //uv - - *pReal++ = x1; *pReal++ = y; *pReal++ = z1; //center position - *pReal++ = +halfXScale; *pReal++ = 0.0f; *pReal++ = 0; *pReal++ = 0; //normal (used to store relative corner positions) - *((uint32*)pReal++) = color; //color - *pReal++ = uvRight; *pReal++ = 1; //uv - - //Update bounds - if (y < minY) minY = y; - if (y + scaleY > maxY) maxY = y + scaleY; - } - - vbuf->unlock(); - subMesh->vertexData->vertexBufferBinding->setBinding(0, vbuf); - - //Populate index buffer - subMesh->indexData->indexStart = 0; - subMesh->indexData->indexCount = 6 * quadCount; - subMesh->indexData->indexBuffer = HardwareBufferManager::getSingleton() - .createIndexBuffer(HardwareIndexBuffer::IT_16BIT, subMesh->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); - uint16* pI = static_cast<uint16*>(subMesh->indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD)); - for (uint16 i = 0; i < quadCount; ++i) - { - uint16 offset = i * 4; - - *pI++ = 0 + offset; - *pI++ = 2 + offset; - *pI++ = 1 + offset; - - *pI++ = 1 + offset; - *pI++ = 2 + offset; - *pI++ = 3 + offset; - } - - subMesh->indexData->indexBuffer->unlock(); - - //Finish up mesh - AxisAlignedBox bounds(page.bounds.left - page.centerPoint.x, minY, page.bounds.top - page.centerPoint.z, - page.bounds.right - page.centerPoint.x, maxY, page.bounds.bottom - page.centerPoint.z); - mesh->_setBounds(bounds); - Vector3 temp = bounds.getMaximum() - bounds.getMinimum(); - mesh->_setBoundingSphereRadius(temp.length() * 0.5f); - - LogManager::getSingleton().setLogDetail(static_cast<LoggingLevel>(0)); - mesh->load(); - LogManager::getSingleton().setLogDetail(LL_NORMAL); - - //Apply grass material to mesh - subMesh->setMaterialName(layer->material->getName()); - - //Return the mesh - return mesh.getPointer(); -} - -GrassLayer::GrassLayer(PagedGeometry *geom, GrassLoader *ldr) -{ GrassLayer::geom = geom; GrassLayer::parent = ldr; @@ -674,8 +72,25 @@ colorMap->unload(); } -void GrassLayer::setMaterialName(const String &matName) +uint32 GrassLayer::calculateMaxGrassCount(float densityFactor, float volume) { + return density * densityFactor * volume; +} + +uint32 GrassLayer::_populateGrassList(PageInfo page, float *posBuff, uint32 grassCount) +{ + if (densityMap){ + if (densityMap->getFilter() == MAPFILTER_NONE) + return _populateGrassList_UnfilteredDM(page, posBuff, grassCount); + else if (densityMap->getFilter() == MAPFILTER_BILINEAR) + return _populateGrassList_BilinearDM(page, posBuff, grassCount); + } + return _populateGrassList_Uniform(page, posBuff, grassCount); + +} + +void GrassLayerBase::setMaterialName(const String &matName) +{ if (material.isNull() || matName != material->getName()){ material = MaterialManager::getSingleton().getByName(matName); if (material.isNull()) @@ -684,13 +99,13 @@ } } -void GrassLayer::setMinimumSize(float width, float height) +void GrassLayerBase::setMinimumSize(float width, float height) { minWidth = width; minHeight = height; } -void GrassLayer::setMaximumSize(float width, float height) +void GrassLayerBase::setMaximumSize(float width, float height) { maxWidth = width; if (maxHeight != height){ @@ -699,7 +114,7 @@ } } -void GrassLayer::setRenderTechnique(GrassTechnique style, bool blendBase) +void GrassLayerBase::setRenderTechnique(GrassTechnique style, bool blendBase) { if (blend != blendBase || renderTechnique != style){ blend = blendBase; @@ -708,7 +123,7 @@ } } -void GrassLayer::setFadeTechnique(FadeTechnique style) +void GrassLayerBase::setFadeTechnique(FadeTechnique style) { if (fadeTechnique != style){ fadeTechnique = style; @@ -716,7 +131,7 @@ } } -void GrassLayer::setAnimationEnabled(bool enabled) +void GrassLayerBase::setAnimationEnabled(bool enabled) { if (animate != enabled){ animate = enabled; @@ -756,14 +171,14 @@ densityMap->setFilter(densityMapFilter); } -unsigned int GrassLayer::_populateGrassList_Uniform(PageInfo page, float *posBuff, unsigned int grassCount) +uint32 GrassLayer::_populateGrassList_Uniform(PageInfo page, float *posBuff, uint32 grassCount) { float *posPtr = posBuff; //No density map if (!minY && !maxY){ //No height range - for (unsigned int i = 0; i < grassCount; ++i){ + for (uint32 i = 0; i < grassCount; ++i){ //Pick a random position float x = Math::RangeRandom(page.bounds.left, page.bounds.right); float z = Math::RangeRandom(page.bounds.top, page.bounds.bottom); @@ -783,7 +198,7 @@ if (minY) min = minY; else min = Math::NEG_INFINITY; if (maxY) max = maxY; else max = Math::POS_INFINITY; - for (unsigned int i = 0; i < grassCount; ++i){ + for (uint32 i = 0; i < grassCount; ++i){ //Pick a random position float x = Math::RangeRandom(page.bounds.left, page.bounds.right); float z = Math::RangeRandom(page.bounds.top, page.bounds.bottom); @@ -809,14 +224,14 @@ return grassCount; } -unsigned int GrassLayer::_populateGrassList_UnfilteredDM(PageInfo page, float *posBuff, unsigned int grassCount) +uint32 GrassLayer::_populateGrassList_UnfilteredDM(PageInfo page, float *posBuff, uint32 grassCount) { float *posPtr = posBuff; //Use density map if (!minY && !maxY){ //No height range - for (unsigned int i = 0; i < grassCount; ++i){ + for (uint32 i = 0; i < grassCount; ++i){ //Pick a random position float x = Math::RangeRandom(page.bounds.left, page.bounds.right); float z = Math::RangeRandom(page.bounds.top, page.bounds.bottom); @@ -835,7 +250,7 @@ if (minY) min = minY; else min = Math::NEG_INFINITY; if (maxY) max = maxY; else max = Math::POS_INFINITY; - for (unsigned int i = 0; i < grassCount; ++i){ + for (uint32 i = 0; i < grassCount; ++i){ //Pick a random position float x = Math::RangeRandom(page.bounds.left, page.bounds.right); float z = Math::RangeRandom(page.bounds.top, page.bounds.bottom); @@ -860,13 +275,13 @@ return grassCount; } -unsigned int GrassLayer::_populateGrassList_BilinearDM(PageInfo page, float *posBuff, unsigned int grassCount) +uint32 GrassLayer::_populateGrassList_BilinearDM(PageInfo page, float *posBuff, uint32 grassCount) { float *posPtr = posBuff; if (!minY && !maxY){ //No height range - for (unsigned int i = 0; i < grassCount; ++i){ + for (uint32 i = 0; i < grassCount; ++i){ //Pick a random position float x = Math::RangeRandom(page.bounds.left, page.bounds.right); float z = Math::RangeRandom(page.bounds.top, page.bounds.bottom); @@ -885,7 +300,7 @@ if (minY) min = minY; else min = Math::NEG_INFINITY; if (maxY) max = maxY; else max = Math::POS_INFINITY; - for (unsigned int i = 0; i < grassCount; ++i){ + for (uint32 i = 0; i < grassCount; ++i){ //Pick a random position float x = Math::RangeRandom(page.bounds.left, page.bounds.right); float z = Math::RangeRandom(page.bounds.top, page.bounds.bottom); @@ -943,7 +358,7 @@ colorMap->setFilter(colorMapFilter); } -void GrassLayer::_updateShaders() +void GrassLayerBase::_updateShaders() { if (shaderNeedsUpdate){ shaderNeedsUpdate = false; @@ -1149,3 +564,4 @@ node->setVisible(visible); } } +} Modified: trunk/python-ogre/ThirdParty/forests/GrassLoader.h =================================================================== --- trunk/python-ogre/ThirdParty/forests/GrassLoader.h 2008-02-24 08:05:30 UTC (rev 578) +++ trunk/python-ogre/ThirdParty/forests/GrassLoader.h 2008-03-09 11:11:30 UTC (rev 579) @@ -1,5 +1,6 @@ /*------------------------------------------------------------------------------------- Copyright (c) 2006 John Judnich +Modified 2008 by Erik Hjortsberg (eri...@it...) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: @@ -14,22 +15,57 @@ #include "PagedGeometry.h" #include "PropertyMaps.h" -#include "OgrePrerequisites.h" -#include "OgreMaterial.h" -#include "OgrePixelFormat.h" -#include "OgreStringConverter.h" +#include <OgrePrerequisites.h> +#include <OgreMaterial.h> +#include <OgrePixelFormat.h> +#include <OgreStringConverter.h> +#include <OgreMeshManager.h> +#include <OgreRoot.h> +#include <OgreTimer.h> +#include <OgreCamera.h> +#include <OgreVector3.h> +#include <OgreQuaternion.h> +#include <OgreEntity.h> +#include <OgreString.h> +#include <OgreStringConverter.h> +#include <OgreMaterialManager.h> +#include <OgreMaterial.h> +#include <OgreHardwareBufferManager.h> +#include <OgreHardwareBuffer.h> +#include <OgreMeshManager.h> +#include <OgreMesh.h> +#include <OgreSubMesh.h> +#include <OgreLogManager.h> +#include <OgreTextureManager.h> +#include <OgreHardwarePixelBuffer.h> +#include <OgreRenderSystem.h> +#include <OgreRenderSystemCapabilities.h> +#include <OgreHighLevelGpuProgram.h> +#include <OgreHighLevelGpuProgramManager.h> + +namespace PagedGeometry { + class GrassLayer; +class GrassLayerBase; /** \brief A PageLoader-derived object you can use with PagedGeometry to produce realistic grass. Using a GrassLoader is simple - simply create an instance, attach it to your PagedGeometry object with PagedGeometry::setPageLoader(), and add your grass. Important: For best performance, it is recommended that you use GrassPage (included in GrassLoader.h) to display geometry loaded by GrassLoader. + This page type is designed for best performance with this grass system. BatchPage will work, although performance will be reduced slightly, and ImpostorPage will run extremely slow. +When creating a GrassLoader you must specify the class which will be used for creating layers. By default a GrassLayer class is provided, which can be used as this: +\code + ::PagedGeometry::GrassLoader<GrassLayer> loader = new ::PagedGeometry::GrassLoader<GrassLayer>(grass); +\endcode +It's also possible for you to provide your own GrassLayer implementation by overriding the class GrassLayerBase. This will allow you to have much more control over how the grass is placed. + + To add grass, just call addLayer(). addLayer() returns a GrassLayer object pointer, which you should use to further configure your newly added grass. Properties like size, density, color, animation, etc. can be controlled through the GrassLayer class. @@ -43,6 +79,7 @@ keep in mind that calculating the height of Ogre's built-in terrain this way can be VERY slow if not done properly, and may cause stuttering due to long paging delays. */ +template <typename TGrassLayer> class GrassLoader: public PageLoader { public: @@ -64,18 +101,18 @@ functions to vary grass size and density levels as desired. \see GrassLayer class for more information. */ - GrassLayer *addLayer(const Ogre::String &material); + TGrassLayer *addLayer(const Ogre::String &material); /** \brief Removes and deletes a grass layer from the scene This function simply deletes a GrassLayer previously created with addLayer(). */ - void deleteLayer(GrassLayer *layer); + void deleteLayer(TGrassLayer *layer); /** \brief Returns a list of added grass layers. This function returns a std::list<GrassLayer*> reference, which contains all grass layers which have been added to this GrassLoader. */ - inline std::list<GrassLayer*> &getLayerList() { return layerList; } + inline std::list<TGrassLayer*> &getLayerList() { return layerList; } /** \brief Sets the global wind direction for this GrassLoader. @@ -179,12 +216,12 @@ friend class GrassLayer; //Helper functions - Ogre::Mesh *generateGrass_QUAD(PageInfo &page, GrassLayer *layer, float *grassPositions, unsigned int grassCount); - Ogre::Mesh *generateGrass_CROSSQUADS(PageInfo &page, GrassLayer *layer, float *grassPositions, unsigned int grassCount); - Ogre::Mesh *generateGrass_SPRITE(PageInfo &page, GrassLayer *layer, float *grassPositions, unsigned int grassCount); + Ogre::Mesh *generateGrass_QUAD(PageInfo &page, TGrassLayer *layer, float *grassPositions, unsigned int grassCount); + Ogre::Mesh *generateGrass_CROSSQUADS(PageInfo &page, TGrassLayer *layer, float *grassPositions, unsigned int grassCount); + Ogre::Mesh *generateGrass_SPRITE(PageInfo &page, TGrassLayer *layer, float *grassPositions, unsigned int grassCount); //List of grass types - std::list<GrassLayer*> layerList; + std::list<TGrassLayer*> layerList; //Height data Ogre::Real (*heightFunction)(Ogre::Real x, Ogre::Real z, void *userData); //Pointer to height function @@ -208,6 +245,9 @@ }; + + + /** \brief A technique used to render grass. Passed to GrassLayer::setRenderTechnique(). */ enum GrassTechnique { @@ -230,8 +270,129 @@ FADETECH_ALPHAGROW }; +class GrassLayerBase +{ +public: + /** \brief Sets the material that is applied to all grass billboards/quads */ + void setMaterialName(const Ogre::String &matName); + /** \brief Sets the minimum size that grass quads/billboards will be */ + void setMinimumSize(float width, float height); + /** \brief Sets the maximum size that grass quads/billboards will be */ + void setMaximumSize(float width, float height); + + /** \brief Sets the technique used to render this grass layer + \param style The GrassTechnique style used to display grass. + \param blendBase Whether or not grass base blending is enabled. + + The "style" setting allows you to choose from various construction methods, such as + sprite-style grass quads, plain 3D quads, etc. See the GrassTechnique documentation + for more information about this option. GRASSTECH_QUAD is used by default. + + Setting "blendBase" to true will enable grass base blending, a technique which helps + reduce the unnatural flat appearance of grass quads near the camera. Since the flatness + is most obvious where the grass intersects the terrain, this technique attempts to + smoothly blend the base of near-by grass into the terrain. + + \note Base blending does not work well with alpha-rejected textures. + */ + void setRenderTechnique(GrassTechnique style, bool blendBase = false); + + /** \brief Sets the technique used when fading out distant grass + \param style The FadeTechnique style used to fade grass. + + This "style" setting allows you to choose from various fade techniques. Depending on + your scene, certain techniques may look better than others. The most compatible method + is FADETECH_ALPHA (used by default), although better results can usually be achieved + with other methods. See the FadeTechnique documentation for more information. + */ + void setFadeTechnique(FadeTechnique style); + + /** \brief Enables/disables animation on this layer + + Always use this function to disable animation, rather than setting SwayLength or SwaySpeed + to 0. This function will use a different vertex shader which means improved performance + when animation is disabled. + */ + void setAnimationEnabled(bool enabled); + + /** \brief Sets how far grass should sway back and forth + + \note Since this is measured in world units, you may have to adjust this depending on + the size of your grass as set by setMinimumSize() and setMaximumSize().*/ + void setSwayLength(float mag) { animMag = mag; } + + /** \brief Sets the sway speed of the grass (measured in "sways-per-second") */ + void setSwaySpeed(float speed) { animSpeed = speed; } + + /** \brief Sets the smooth distribution (positional phase shift) of the grass swaying animation + + If you set this to 0, grass animation will look very unnatural, since all the grass sway motions + will be in perfect synchronization (everything sways to the right, then everything sways to the + left, etc.) This sets the "positional phase shift", which gives the grass a "wave" like phase + distribution. The higher this value is, the more "chaotic" the wind will appear. Lower values give + a smoother breeze appearance, but values too high can look unrealistic. + */ + void setSwayDistribution(float freq) { animFreq = freq; } + + /** \brief Sets the boundaries of the density/color maps + \param bounds The map boundary + + By default, the GrassLayer has no knowledge of your terrain/world boundaries, so you must + use this function to specify a rectangular/square area of your world, otherwise density/color maps + won't work properly. The boundary given to this function defines the area where density/color + maps take effect. Normally this is set to your terrain's bounds so the density/color map is aligned + to your heightmap, but you could apply it anywhere you want. + + \note The grass system is infinite, so there's no need to worry about using too expansive + boundaries. This setting simply configures the behavior of density and color maps. */ + virtual void setMapBounds(const Ogre::TRect<Ogre::Real> &bounds) + { + mapBounds = bounds; + } + + + /** + * Calculates the max number of grass instances for this layer. + * @param densityFactor The density factor set on the grass loader + * @param volume The volume, in world units, to fill + * @return The max number of grass instances to create. + */ + virtual unsigned int calculateMaxGrassCount(float densityFactor, float volume) = 0; + +protected: + + //Used by GrassLoader::loadPage() - populates an array with grass. + //Returns the final number of grasses, which will always be <= grassCount + virtual unsigned int _populateGrassList(PageInfo page, float *posBuff, unsigned int grassCount) = 0; + + //Updates the vertex shader used by this layer based on the animate enable status + void _updateShaders(); + + //Grass material/shape properties + Ogre::MaterialPtr material; + float minWidth, maxWidth; + float minHeight, maxHeight; + + FadeTechnique fadeTechnique; + GrassTechnique renderTechnique; + + //Property maps + Ogre::TRect<Ogre::Real> mapBounds; + + //Grass shader properties + bool animate, blend, shaderNeedsUpdate; + float animMag, animSpeed, animFreq; + + //Current frame of animation for this layer + float waveCount; + + PagedGeometry *geom; + +}; + + /** \brief A data structure giving you full control over grass properties. Grass is added to the scene through GrassLoader::addLayer(). Through this class you @@ -242,18 +403,10 @@ with GrassLoader::addLayer(), and may not be deleted manually (they will be deleted when the associated GrassLoader is deleted). */ -class GrassLayer +class GrassLayer : public GrassLayerBase { public: - /** \brief Sets the material that is applied to all grass billboards/quads */ - void setMaterialName(const Ogre::String &matName); - /** \brief Sets the minimum size that grass quads/billboards will be */ - void setMinimumSize(float width, float height); - - /** \brief Sets the maximum size that grass quads/billboards will be */ - void setMaximumSize(float width, float height); - /** \brief Sets the maximum density (measured in grass quads/billboards per square unit) of grass */ void setDensity(float density) { this->density = density; } @@ -359,26 +512,6 @@ */ void setColorMapFilter(MapFilter filter); - /** \brief Sets the boundaries of the density/color maps - \param bounds The map boundary - - By default, the GrassLayer has no knowledge of your terrain/world boundaries, so you must - use this function to specify a rectangular/square area of your world, otherwise density/color maps - won't work properly. The boundary given to this function defines the area where density/color - maps take effect. Normally this is set to your terrain's bounds so the density/color map is aligned - to your heightmap, but you could apply it anywhere you want. - - \note The grass system is infinite, so there's no need to worry about using too expansive - boundaries. This setting simply configures the behavior of density and color maps. */ - void setMapBounds(const Ogre::TRect<Ogre::Real> &bounds) - { - mapBounds = bounds; - if (densityMap) - densityMap->setMapBounds(mapBounds); - if (colorMap) - colorMap->setMapBounds(mapBounds); - } - /** \brief Gets a pointer to the density map being used You can use this function to access the internal density map object used by the GrassLoader. @@ -401,71 +534,62 @@ don't, the grass you see will remain unchanged. */ ColorMap *getColorMap() { return colorMap; } - /** \brief Sets the technique used to render this grass layer - \param style The GrassTechnique style used to display grass. - \param blendBase Whether or not grass base blending is enabled. - - The "style" setting allows you to choose from various construction methods, such as - sprite-style grass quads, plain 3D quads, etc. See the GrassTechnique documentation - for more information about this option. GRASSTECH_QUAD is used by default. - Setting "blendBase" to true will enable grass base blending, a technique which helps - reduce the unnatural flat appearance of grass quads near the camera. Since the flatness - is most obvious where the grass intersects the terrain, this technique attempts to - smoothly blend the base of near-by grass into the terrain. - - \note Base blending does not work well with alpha-rejected textures. - */ - void setRenderTechnique(GrassTechnique style, bool blendBase = false); - - /** \brief Sets the technique used when fading out distant grass - \param style The FadeTechnique style used to fade grass. + /** \brief Sets the boundaries of the density/color maps + \param bounds The map boundary - This "style" setting allows you to choose from various fade techniques. Depending on - your scene, certain techniques may look better than others. The most compatible method - is FADETECH_ALPHA (used by default), although better results can usually be achieved - with other methods.... [truncated message content] |