1 /*------------------------------------------------------------------------------------- 2 Copyright (c) 2006 John Judnich 3 4 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. 5 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: 6 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 7 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 8 3. This notice may not be removed or altered from any source distribution. 9 -------------------------------------------------------------------------------------*/ 10 #ifndef __BatchedGeometry_H__ 11 #define __BatchedGeometry_H__ 12 13 #include <OgrePrerequisites.h> 14 #include <OgreMovableObject.h> 15 #include <OgreSceneNode.h> 16 #include <OgreMaterialManager.h> 17 18 namespace Forests 19 { 20 //-------------------------------------------------------------------------- 21 /// A "lightweight" version of Ogre::StaticGeometry, which gives you a little 22 /// more control over the batch materials, etc. 23 class BatchedGeometry : public Ogre::MovableObject 24 { 25 public: 26 //-------------------------------------------------------------------------- 27 /// Visible chunk of geometry. 28 class SubBatch : public Ogre::Renderable 29 { 30 protected: 31 // A structure defining the desired position/orientation/scale of a batched mesh. The 32 // SubMesh is not specified since that can be determined by which MeshQueue this belongs to. 33 struct QueuedMesh 34 { 35 QueuedMesh(Ogre::SubMesh* sm, const Ogre::Vector3 &pos, const Ogre::Quaternion &ori, 36 const Ogre::Vector3 &scl, const Ogre::ColourValue &clr, void *userData_ = 0) : subMeshQueuedMesh37 subMesh (sm), 38 position (pos), 39 orientation (ori), 40 scale (scl), 41 color (clr), 42 userData (userData_) 43 { 44 // empty 45 } 46 47 Ogre::SubMesh* subMesh; 48 Ogre::Vector3 position; 49 Ogre::Quaternion orientation; 50 Ogre::Vector3 scale; 51 Ogre::ColourValue color; 52 void* userData; 53 }; 54 55 /// Queue of meshes for build batch of geometry 56 typedef std::vector<QueuedMesh> TMeshQueue; 57 58 59 // Function section 60 61 public: 62 /// Constructor 63 SubBatch(BatchedGeometry *parent, Ogre::SubEntity *ent); 64 /// Destructor 65 ~SubBatch(); 66 67 /// 68 void addSubEntity(Ogre::SubEntity *ent, const Ogre::Vector3 &position, 69 const Ogre::Quaternion &orientation, const Ogre::Vector3 &scale, 70 const Ogre::ColourValue &color = Ogre::ColourValue::White, void* userData = NULL); 71 72 /// Build (assemble a vertex/index buffers) geometry for rendering 73 virtual void build(); 74 /// 75 void clear(); 76 77 /// 78 void addSelfToRenderQueue(Ogre::RenderQueueGroup *rqg); 79 /// 80 void getRenderOperation(Ogre::RenderOperation& op); 81 /// 82 Ogre::Real getSquaredViewDepth(const Ogre::Camera* cam) const; 83 /// 84 const Ogre::LightList& getLights(void) const; 85 86 /// setMaterial(Ogre::MaterialPtr & mat)87 void setMaterial(Ogre::MaterialPtr &mat) { m_ptrMaterial = mat; } 88 void setMaterialName(const Ogre::String &mat, const Ogre::String &rg = 89 Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME) 90 { 91 m_ptrMaterial = Ogre::MaterialManager::getSingleton().getByName(mat, rg).staticCast<Ogre::Material>(); 92 } 93 94 /// Get material name. Be careful, resource group name missing getMaterialName()95 const Ogre::String& getMaterialName() const { return m_ptrMaterial->getName(); } getTechnique()96 Ogre::Technique *getTechnique() const { return m_pBestTechnique; } getMaterial(void)97 const Ogre::MaterialPtr& getMaterial(void) const { return m_ptrMaterial; } getWorldTransforms(Ogre::Matrix4 * xform)98 void getWorldTransforms(Ogre::Matrix4* xform) const { *xform = m_pParentGeom->_getParentNodeFullTransform(); } getWorldOrientation(void)99 const Ogre::Quaternion& getWorldOrientation(void) const { return m_pParentGeom->m_pSceneNode->_getDerivedOrientation(); } getWorldPosition(void)100 const Ogre::Vector3& getWorldPosition(void) const { return m_pParentGeom->m_pSceneNode->_getDerivedPosition(); } castsShadows(void)101 bool castsShadows(void) const { return m_pParentGeom->getCastShadows(); } 102 103 // internal fuctions 104 private: 105 /// Build vertex of QueuedMesh if it have identity orientation 106 static void _buildIdentiryOrientation(const QueuedMesh &queuedMesh, const Ogre::Vector3 &parentGeomCenter, 107 const std::vector<Ogre::VertexDeclaration::VertexElementList> &vertexBufferElements, std::vector<Ogre::uchar*> &vertexBuffers, 108 Ogre::VertexData *dst); 109 /// Build vertex of QueuedMesh if it have some orientation 110 static void _buildFullTransform(const QueuedMesh &queuedMesh, const Ogre::Vector3 &parentGeomCenter, 111 const std::vector<Ogre::VertexDeclaration::VertexElementList> &vertexBufferElements, std::vector<Ogre::uchar*> &vertexBuffers, 112 Ogre::VertexData *dst); 113 114 115 // Data section class SubBatch 116 117 public: 118 Ogre::VertexData* m_pVertexData; ///< 119 Ogre::IndexData* m_pIndexData; ///< 120 121 protected: 122 bool m_Built; ///< 123 bool m_RequireVertexColors; ///< 124 Ogre::SubMesh* m_pSubMesh; ///< Ogre::SubMesh for Index/Vertex buffers manipulation 125 BatchedGeometry* m_pParentGeom; ///< 126 Ogre::MaterialPtr m_ptrMaterial; ///< 127 TMeshQueue m_queueMesh; ///< The list of meshes to be added to this batch 128 129 private: 130 Ogre::Technique* m_pBestTechnique; ///< Technique recalculated every frame 131 132 }; // end class SubBatch 133 //----------------------------------------------------------------------- 134 135 /// Stores a list of GeomBatch'es, using a format string (generated with getGeometryFormatString()) as the key value 136 typedef std::map<Ogre::String, SubBatch*> TSubBatchMap; 137 typedef Ogre::MapIterator<TSubBatchMap> TSubBatchIterator; 138 typedef Ogre::ConstMapIterator<TSubBatchMap> TConstSubBatchIterator; 139 140 public: 141 142 /// Constructor 143 BatchedGeometry(Ogre::SceneManager *mgr, Ogre::SceneNode *rootSceneNode); 144 ~BatchedGeometry(); 145 getSubBatchIterator()146 TConstSubBatchIterator getSubBatchIterator() const { return TConstSubBatchIterator(m_mapSubBatch); } getSubBatchIterator()147 TSubBatchIterator getSubBatchIterator() { return TSubBatchIterator(m_mapSubBatch); } 148 149 virtual void addEntity(Ogre::Entity *ent, const Ogre::Vector3 &position, 150 const Ogre::Quaternion &orientation = Ogre::Quaternion::IDENTITY, 151 const Ogre::Vector3 &scale = Ogre::Vector3::UNIT_SCALE, 152 const Ogre::ColourValue &color = Ogre::ColourValue::White); 153 154 void build(); 155 void clear(); 156 157 Ogre::Vector3 _convertToLocal(const Ogre::Vector3 &globalVec) const; 158 getBoundingBox(void)159 const Ogre::AxisAlignedBox &getBoundingBox(void) const { return m_boundsAAB; } getBoundingRadius(void)160 Ogre::Real getBoundingRadius(void) const { return m_fRadius; } 161 162 private: 163 bool isVisible(); 164 const Ogre::String& getMovableType(void) const; visitRenderables(Ogre::Renderable::Visitor * visitor,bool debugRenderables)165 void visitRenderables(Ogre::Renderable::Visitor* visitor, bool debugRenderables) { /* empty */ } 166 void _notifyCurrentCamera(Ogre::Camera *cam); 167 void _updateRenderQueue(Ogre::RenderQueue *queue); 168 169 protected: 170 static Ogre::String getFormatString(Ogre::SubEntity *ent); 171 static void extractVertexDataFromShared(const Ogre::MeshPtr &mesh); 172 173 174 // Data section of BatchedGeometry class 175 protected: 176 bool m_Built; 177 bool m_BoundsUndefined; 178 Ogre::Vector3 m_vecCenter; 179 Ogre::AxisAlignedBox m_boundsAAB; 180 TSubBatchMap m_mapSubBatch; 181 /// Internal matrix for remap vertex type to vertex size instead call VertexElement::getTypeSize 182 static const size_t s_vertexType2Size[Ogre::VET_COLOUR_ABGR + 1]; 183 184 private: 185 bool m_bWithinFarDistance; 186 Ogre::Real m_fRadius; 187 Ogre::Real m_fMinDistanceSquared; 188 Ogre::SceneManager* m_pSceneMgr; 189 Ogre::SceneNode* m_pSceneNode; 190 Ogre::SceneNode* m_pParentSceneNode; 191 }; 192 193 } 194 195 #endif 196