[657] | 1 | /*
|
---|
| 2 | -----------------------------------------------------------------------------
|
---|
| 3 | This source file is part of OGRE
|
---|
| 4 | (Object-oriented Graphics Rendering Engine)
|
---|
| 5 | For the latest info, see http://www.ogre3d.org/
|
---|
| 6 |
|
---|
| 7 | Copyright (c) 2000-2005 The OGRE Team
|
---|
| 8 | Also see acknowledgements in Readme.html
|
---|
| 9 |
|
---|
| 10 | This program is free software; you can redistribute it and/or modify it under
|
---|
| 11 | the terms of the GNU Lesser General Public License as published by the Free Software
|
---|
| 12 | Foundation; either version 2 of the License, or (at your option) any later
|
---|
| 13 | version.
|
---|
| 14 |
|
---|
| 15 | This program is distributed in the hope that it will be useful, but WITHOUT
|
---|
| 16 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
---|
| 17 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
---|
| 18 |
|
---|
| 19 | You should have received a copy of the GNU Lesser General Public License along with
|
---|
| 20 | this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
---|
| 21 | Place - Suite 330, Boston, MA 02111-1307, USA, or go to
|
---|
| 22 | http://www.gnu.org/copyleft/lesser.txt.
|
---|
| 23 | -----------------------------------------------------------------------------
|
---|
| 24 | */
|
---|
| 25 | #ifndef __Mesh_H__
|
---|
| 26 | #define __Mesh_H__
|
---|
| 27 |
|
---|
| 28 | #include "OgrePrerequisites.h"
|
---|
| 29 |
|
---|
| 30 | #include "OgreResource.h"
|
---|
| 31 | #include "OgreVertexIndexData.h"
|
---|
| 32 | #include "OgreAxisAlignedBox.h"
|
---|
| 33 | #include "OgreVertexBoneAssignment.h"
|
---|
| 34 | #include "OgreAnimationState.h"
|
---|
| 35 | #include "OgreIteratorWrappers.h"
|
---|
| 36 | #include "OgreProgressiveMesh.h"
|
---|
| 37 | #include "OgreHardwareVertexBuffer.h"
|
---|
| 38 | #include "OgreSkeleton.h"
|
---|
| 39 |
|
---|
| 40 |
|
---|
| 41 | namespace Ogre {
|
---|
| 42 |
|
---|
| 43 |
|
---|
| 44 | /** Resource holding data about 3D mesh.
|
---|
| 45 | @remarks
|
---|
| 46 | This class holds the data used to represent a discrete
|
---|
| 47 | 3-dimensional object. Mesh data usually contains more
|
---|
| 48 | than just vertices and triangle information; it also
|
---|
| 49 | includes references to materials (and the faces which use them),
|
---|
| 50 | level-of-detail reduction information, convex hull definition,
|
---|
| 51 | skeleton/bones information, keyframe animation etc.
|
---|
| 52 | However, it is important to note the emphasis on the word
|
---|
| 53 | 'discrete' here. This class does not cover the large-scale
|
---|
| 54 | sprawling geometry found in level / landscape data.
|
---|
| 55 | @par
|
---|
| 56 | Multiple world objects can (indeed should) be created from a
|
---|
| 57 | single mesh object - see the Entity class for more info.
|
---|
| 58 | The mesh object will have it's own default
|
---|
| 59 | material properties, but potentially each world instance may
|
---|
| 60 | wish to customise the materials from the original. When the object
|
---|
| 61 | is instantiated into a scene node, the mesh material properties
|
---|
| 62 | will be taken by default but may be changed. These properties
|
---|
| 63 | are actually held at the SubMesh level since a single mesh may
|
---|
| 64 | have parts with different materials.
|
---|
| 65 | @par
|
---|
| 66 | As described above, because the mesh may have sections of differing
|
---|
| 67 | material properties, a mesh is inherently a compound contruct,
|
---|
| 68 | consisting of one or more SubMesh objects.
|
---|
| 69 | However, it strongly 'owns' it's SubMeshes such that they
|
---|
| 70 | are loaded / unloaded at the same time. This is contrary to
|
---|
| 71 | the approach taken to hierarchically related (but loosely owned)
|
---|
| 72 | scene nodes, where data is loaded / unloaded separately. Note
|
---|
| 73 | also that mesh sub-sections (when used in an instantiated object)
|
---|
| 74 | share the same scene node as the parent.
|
---|
| 75 | */
|
---|
| 76 |
|
---|
| 77 |
|
---|
| 78 | struct MeshLodUsage;
|
---|
| 79 |
|
---|
| 80 | class _OgreExport Mesh: public Resource
|
---|
| 81 | {
|
---|
| 82 | friend class SubMesh;
|
---|
| 83 | friend class MeshSerializerImpl;
|
---|
| 84 | friend class MeshSerializerImpl_v1_2;
|
---|
| 85 | friend class MeshSerializerImpl_v1_1;
|
---|
| 86 |
|
---|
| 87 | public:
|
---|
| 88 | typedef std::vector<Real> LodDistanceList;
|
---|
| 89 | /// Multimap of vertex bone assignments (orders by vertex index)
|
---|
| 90 | typedef std::multimap<size_t, VertexBoneAssignment> VertexBoneAssignmentList;
|
---|
| 91 | typedef MapIterator<VertexBoneAssignmentList> BoneAssignmentIterator;
|
---|
| 92 | typedef std::vector<SubMesh*> SubMeshList;
|
---|
| 93 |
|
---|
| 94 | protected:
|
---|
| 95 | /** A list of submeshes which make up this mesh.
|
---|
| 96 | Each mesh is made up of 1 or more submeshes, which
|
---|
| 97 | are each based on a single material and can have their
|
---|
| 98 | own vertex data (they may not - they can share vertex data
|
---|
| 99 | from the Mesh, depending on preference).
|
---|
| 100 | */
|
---|
| 101 | SubMeshList mSubMeshList;
|
---|
| 102 |
|
---|
| 103 | /** Internal method for making the space for a 3D texture coord buffer to hold tangents. */
|
---|
| 104 | void organiseTangentsBuffer(VertexData *vertexData, unsigned short destCoordSet);
|
---|
| 105 |
|
---|
| 106 | public:
|
---|
| 107 | /** A hashmap used to store optional SubMesh names.
|
---|
| 108 | Translates a name into SubMesh index
|
---|
| 109 | */
|
---|
| 110 | typedef HashMap<String, ushort> SubMeshNameMap ;
|
---|
| 111 | protected:
|
---|
| 112 | SubMeshNameMap mSubMeshNameMap ;
|
---|
| 113 |
|
---|
| 114 | /// Local bounding box volume
|
---|
| 115 | AxisAlignedBox mAABB;
|
---|
| 116 | /// Local bounding sphere radius (centered on object)
|
---|
| 117 | Real mBoundRadius;
|
---|
| 118 |
|
---|
| 119 | /// Optional linked skeleton
|
---|
| 120 | String mSkeletonName;
|
---|
| 121 | SkeletonPtr mSkeleton;
|
---|
| 122 |
|
---|
| 123 |
|
---|
| 124 | VertexBoneAssignmentList mBoneAssignments;
|
---|
| 125 |
|
---|
| 126 | /// Flag indicating that bone assignments need to be recompiled
|
---|
| 127 | bool mBoneAssignmentsOutOfDate;
|
---|
| 128 |
|
---|
| 129 | /** Compile bone assignments into blend index and weight buffers. */
|
---|
| 130 | void compileBoneAssignments(const VertexBoneAssignmentList& boneAssignments,
|
---|
| 131 | unsigned short numBlendWeightsPerVertex,
|
---|
| 132 | VertexData* targetVertexData);
|
---|
| 133 | /** Software blending oriented bone assignment compilation */
|
---|
| 134 | void compileBoneAssignmentsSoftware(const VertexBoneAssignmentList& boneAssignments,
|
---|
| 135 | unsigned short numBlendWeightsPerVertex, VertexData* targetVertexData);
|
---|
| 136 |
|
---|
| 137 |
|
---|
| 138 | bool mIsLodManual;
|
---|
| 139 | ushort mNumLods;
|
---|
| 140 | typedef std::vector<MeshLodUsage> MeshLodUsageList;
|
---|
| 141 | MeshLodUsageList mMeshLodUsageList;
|
---|
| 142 |
|
---|
| 143 | HardwareBuffer::Usage mVertexBufferUsage;
|
---|
| 144 | HardwareBuffer::Usage mIndexBufferUsage;
|
---|
| 145 | bool mVertexBufferShadowBuffer;
|
---|
| 146 | bool mIndexBufferShadowBuffer;
|
---|
| 147 |
|
---|
| 148 |
|
---|
| 149 | bool mPreparedForShadowVolumes;
|
---|
| 150 | bool mEdgeListsBuilt;
|
---|
| 151 | bool mAutoBuildEdgeLists;
|
---|
| 152 |
|
---|
| 153 | /// @copydoc Resource::loadImpl
|
---|
| 154 | void loadImpl(void);
|
---|
| 155 | /// @copydoc Resource::unloadImpl
|
---|
| 156 | void unloadImpl(void);
|
---|
| 157 | /// @copydoc Resource::calculateSize
|
---|
| 158 | size_t calculateSize(void) const;
|
---|
| 159 |
|
---|
| 160 | public:
|
---|
| 161 | /** Default constructor - used by MeshManager
|
---|
| 162 | @warning
|
---|
| 163 | Do not call this method directly.
|
---|
| 164 | */
|
---|
| 165 | Mesh(ResourceManager* creator, const String& name, ResourceHandle handle,
|
---|
| 166 | const String& group, bool isManual = false, ManualResourceLoader* loader = 0);
|
---|
| 167 | ~Mesh();
|
---|
| 168 |
|
---|
| 169 | /// @copydoc Resource::load
|
---|
| 170 | void load(void);
|
---|
| 171 |
|
---|
| 172 | // NB All methods below are non-virtual since they will be
|
---|
| 173 | // called in the rendering loop - speed is of the essence.
|
---|
| 174 |
|
---|
| 175 | /** Creates a new SubMesh.
|
---|
| 176 | @remarks
|
---|
| 177 | Method for manually creating geometry for the mesh.
|
---|
| 178 | Note - use with extreme caution - you must be sure that
|
---|
| 179 | you have set up the geometry properly.
|
---|
| 180 | */
|
---|
| 181 | SubMesh* createSubMesh(void);
|
---|
| 182 |
|
---|
| 183 | /** Creates a new SubMesh and gives it a name
|
---|
| 184 | */
|
---|
| 185 | SubMesh* createSubMesh(const String& name);
|
---|
| 186 |
|
---|
| 187 | /** Gives a name to a SubMesh
|
---|
| 188 | */
|
---|
| 189 | void nameSubMesh(const String& name, ushort index);
|
---|
| 190 |
|
---|
| 191 | /** Gets the index of a submesh with a given name.
|
---|
| 192 | @remarks
|
---|
| 193 | Useful if you identify the SubMeshes by name (using nameSubMesh)
|
---|
| 194 | but wish to have faster repeat access.
|
---|
| 195 | */
|
---|
| 196 | ushort _getSubMeshIndex(const String& name) const;
|
---|
| 197 |
|
---|
| 198 | /** Gets the number of sub meshes which comprise this mesh.
|
---|
| 199 | */
|
---|
| 200 | unsigned short getNumSubMeshes(void) const;
|
---|
| 201 |
|
---|
| 202 | /** Gets a pointer to the submesh indicated by the index.
|
---|
| 203 | */
|
---|
| 204 | SubMesh* getSubMesh(unsigned short index) const;
|
---|
| 205 |
|
---|
| 206 | /** Gets a SubMesh by name
|
---|
| 207 | */
|
---|
| 208 | SubMesh* getSubMesh(const String& name) const ;
|
---|
| 209 |
|
---|
| 210 | typedef VectorIterator<SubMeshList> SubMeshIterator;
|
---|
| 211 | /// Gets an iterator over the available submeshes
|
---|
| 212 | SubMeshIterator getSubMeshIterator(void)
|
---|
| 213 | { return SubMeshIterator(mSubMeshList.begin(), mSubMeshList.end()); }
|
---|
| 214 |
|
---|
| 215 | /** Shared vertex data.
|
---|
| 216 | @remarks
|
---|
| 217 | This vertex data can be shared among multiple submeshes. SubMeshes may not have
|
---|
| 218 | their own VertexData, they may share this one.
|
---|
| 219 | @par
|
---|
| 220 | The use of shared or non-shared buffers is determined when
|
---|
| 221 | model data is converted to the OGRE .mesh format.
|
---|
| 222 | */
|
---|
| 223 | VertexData *sharedVertexData;
|
---|
| 224 |
|
---|
| 225 | /** Makes a copy of this mesh object and gives it a new name.
|
---|
| 226 | @remarks
|
---|
| 227 | This is useful if you want to tweak an existing mesh without affecting the original one. The
|
---|
| 228 | newly cloned mesh is registered with the MeshManager under the new name.
|
---|
| 229 | @param newName The name to give the clone
|
---|
| 230 | @param newGroup Optional name of the new group to assign the clone to;
|
---|
| 231 | if you leave this blank, the clone will be assigned to the same
|
---|
| 232 | group as this Mesh.
|
---|
| 233 | */
|
---|
| 234 | MeshPtr clone(const String& newName, const String& newGroup = StringUtil::BLANK);
|
---|
| 235 |
|
---|
| 236 | /** Get the axis-aligned bounding box for this mesh.
|
---|
| 237 | */
|
---|
| 238 | const AxisAlignedBox& getBounds(void) const;
|
---|
| 239 |
|
---|
| 240 | /** Gets the radius of the bounding sphere surrounding this mesh. */
|
---|
| 241 | Real getBoundingSphereRadius(void) const;
|
---|
| 242 |
|
---|
| 243 | /** Manually set the bounding box for this Mesh.
|
---|
| 244 | @remarks
|
---|
| 245 | Calling this method is required when building manual meshes now, because OGRE can no longer
|
---|
| 246 | update the bounds for you, because it cannot necessarily read vertex data back from
|
---|
| 247 | the vertex buffers which this mesh uses (they very well might be write-only, and even
|
---|
| 248 | if they are not, reading data from a hardware buffer is a bottleneck).
|
---|
| 249 | @param pad If true, a certain padding will be added to the bounding box to separate it from the mesh
|
---|
| 250 | */
|
---|
| 251 | void _setBounds(const AxisAlignedBox& bounds, bool pad = true);
|
---|
| 252 |
|
---|
| 253 | /** Manually set the bounding radius.
|
---|
| 254 | @remarks
|
---|
| 255 | Calling this method is required when building manual meshes now, because OGRE can no longer
|
---|
| 256 | update the bounds for you, because it cannot necessarily read vertex data back from
|
---|
| 257 | the vertex buffers which this mesh uses (they very well might be write-only, and even
|
---|
| 258 | if they are not, reading data from a hardware buffer is a bottleneck).
|
---|
| 259 | */
|
---|
| 260 | void _setBoundingSphereRadius(Real radius);
|
---|
| 261 |
|
---|
| 262 | /** Sets the name of the skeleton this Mesh uses for animation.
|
---|
| 263 | @remarks
|
---|
| 264 | Meshes can optionally be assigned a skeleton which can be used to animate
|
---|
| 265 | the mesh through bone assignments. The default is for the Mesh to use no
|
---|
| 266 | skeleton. Calling this method with a valid skeleton filename will cause the
|
---|
| 267 | skeleton to be loaded if it is not already (a single skeleton can be shared
|
---|
| 268 | by many Mesh objects).
|
---|
| 269 | @param skelName The name of the .skeleton file to use, or an empty string to use
|
---|
| 270 | no skeleton
|
---|
| 271 | */
|
---|
| 272 | void setSkeletonName(const String& skelName);
|
---|
| 273 |
|
---|
| 274 | /** Returns true if this Mesh has a linked Skeleton. */
|
---|
| 275 | bool hasSkeleton(void) const;
|
---|
| 276 |
|
---|
| 277 | /** Gets a pointer to any linked Skeleton.
|
---|
| 278 | @returns Weak reference to the skeleton - copy this if you want to hold a strong pointer.
|
---|
| 279 | */
|
---|
| 280 | const SkeletonPtr& getSkeleton(void) const;
|
---|
| 281 |
|
---|
| 282 | /** Gets the name of any linked Skeleton */
|
---|
| 283 | const String& getSkeletonName(void) const;
|
---|
| 284 | /** Initialise an animation set suitable for use with this mesh.
|
---|
| 285 | @remarks
|
---|
| 286 | Only recommended for use inside the engine, not by applications.
|
---|
| 287 | */
|
---|
| 288 | void _initAnimationState(AnimationStateSet* animSet);
|
---|
| 289 |
|
---|
| 290 | /** Assigns a vertex to a bone with a given weight, for skeletal animation.
|
---|
| 291 | @remarks
|
---|
| 292 | This method is only valid after calling setSkeletonName.
|
---|
| 293 | Since this is a one-off process there exists only 'addBoneAssignment' and
|
---|
| 294 | 'clearBoneAssignments' methods, no 'editBoneAssignment'. You should not need
|
---|
| 295 | to modify bone assignments during rendering (only the positions of bones) and OGRE
|
---|
| 296 | reserves the right to do some internal data reformatting of this information, depending
|
---|
| 297 | on render system requirements.
|
---|
| 298 | @par
|
---|
| 299 | This method is for assigning weights to the shared geometry of the Mesh. To assign
|
---|
| 300 | weights to the per-SubMesh geometry, see the equivalent methods on SubMesh.
|
---|
| 301 | */
|
---|
| 302 | void addBoneAssignment(const VertexBoneAssignment& vertBoneAssign);
|
---|
| 303 |
|
---|
| 304 | /** Removes all bone assignments for this mesh.
|
---|
| 305 | @remarks
|
---|
| 306 | This method is for modifying weights to the shared geometry of the Mesh. To assign
|
---|
| 307 | weights to the per-SubMesh geometry, see the equivalent methods on SubMesh.
|
---|
| 308 | */
|
---|
| 309 | void clearBoneAssignments(void);
|
---|
| 310 |
|
---|
| 311 | /** Internal notification, used to tell the Mesh which Skeleton to use without loading it.
|
---|
| 312 | @remarks
|
---|
| 313 | This is only here for unusual situation where you want to manually set up a
|
---|
| 314 | Skeleton. Best to let OGRE deal with this, don't call it yourself unless you
|
---|
| 315 | really know what you're doing.
|
---|
| 316 | */
|
---|
| 317 | void _notifySkeleton(SkeletonPtr& pSkel);
|
---|
| 318 |
|
---|
| 319 |
|
---|
| 320 | /** Gets an iterator for access all bone assignments.
|
---|
| 321 | */
|
---|
| 322 | BoneAssignmentIterator getBoneAssignmentIterator(void);
|
---|
| 323 |
|
---|
| 324 |
|
---|
| 325 | /** Automatically generates lower level of detail versions of this mesh for use
|
---|
| 326 | when a simpler version of the model is acceptable for rendering.
|
---|
| 327 | @remarks
|
---|
| 328 | There are 2 ways that you can create level-of-detail (LOD) versions of a mesh;
|
---|
| 329 | the first is to call this method, which does fairly extensive calculations to
|
---|
| 330 | work out how to simplify the mesh whilst having the minimum affect on the model.
|
---|
| 331 | The alternative is to actually create simpler versions of the mesh yourself in
|
---|
| 332 | a modelling tool, and having exported them, tell the 'master' mesh to use these
|
---|
| 333 | alternative meshes for lower detail versions; this is done by calling the
|
---|
| 334 | createManualLodLevel method.
|
---|
| 335 | @par
|
---|
| 336 | As well as creating the lower detail versions of the mesh, this method will
|
---|
| 337 | also associate them with depth values. As soon as an object is at least as far
|
---|
| 338 | away from the camera as the depth value associated with it's LOD, it will drop
|
---|
| 339 | to that level of detail.
|
---|
| 340 | @par
|
---|
| 341 | I recommend calling this method before mesh export, not at runtime.
|
---|
| 342 | @param lodDistances A list of depth values indicating the distances at which new lods should be
|
---|
| 343 | generated.
|
---|
| 344 | @param reductionMethod The way to determine the number of vertices collapsed per LOD
|
---|
| 345 | @param reductionValue Meaning depends on reductionMethod, typically either the proportion
|
---|
| 346 | of remaining vertices to collapse or a fixed number of vertices.
|
---|
| 347 | */
|
---|
| 348 | void generateLodLevels(const LodDistanceList& lodDistances,
|
---|
| 349 | ProgressiveMesh::VertexReductionQuota reductionMethod, Real reductionValue);
|
---|
| 350 |
|
---|
| 351 | /** Returns the number of levels of detail that this mesh supports.
|
---|
| 352 | @remarks
|
---|
| 353 | This number includes the original model.
|
---|
| 354 | */
|
---|
| 355 | ushort getNumLodLevels(void) const;
|
---|
| 356 | /** Gets details of the numbered level of detail entry. */
|
---|
| 357 | const MeshLodUsage& getLodLevel(ushort index) const;
|
---|
| 358 | /** Adds a new manual level-of-detail entry to this Mesh.
|
---|
| 359 | @remarks
|
---|
| 360 | As an alternative to generating lower level of detail versions of a mesh, you can
|
---|
| 361 | use your own manually modelled meshes as lower level versions. This lets you
|
---|
| 362 | have complete control over the LOD, and in addition lets you scale down other
|
---|
| 363 | aspects of the model which cannot be done using the generated method; for example,
|
---|
| 364 | you could use less detailed materials and / or use less bones in the skeleton if
|
---|
| 365 | this is an animated mesh. Therefore for complex models you are likely to be better off
|
---|
| 366 | modelling your LODs yourself and using this method, whilst for models with fairly
|
---|
| 367 | simple materials and no animation you can just use the generateLodLevels method.
|
---|
| 368 | @param fromDepth The z value from which this Lod will apply.
|
---|
| 369 | @param meshName The name of the mesh which will be the lower level detail version.
|
---|
| 370 | */
|
---|
| 371 | void createManualLodLevel(Real fromDepth, const String& meshName);
|
---|
| 372 |
|
---|
| 373 | /** Changes the alternate mesh to use as a manual LOD at the given index.
|
---|
| 374 | @remarks
|
---|
| 375 | Note that the index of a LOD may change if you insert other LODs. If in doubt,
|
---|
| 376 | use getLodIndex().
|
---|
| 377 | @param index The index of the level to be changed
|
---|
| 378 | @param meshName The name of the mesh which will be the lower level detail version.
|
---|
| 379 | */
|
---|
| 380 | void updateManualLodLevel(ushort index, const String& meshName);
|
---|
| 381 |
|
---|
| 382 | /** Retrieves the level of detail index for the given depth value.
|
---|
| 383 | */
|
---|
| 384 | ushort getLodIndex(Real depth) const;
|
---|
| 385 |
|
---|
| 386 | /** Retrieves the level of detail index for the given squared depth value.
|
---|
| 387 | @remarks
|
---|
| 388 | Internally the lods are stored at squared depths to avoid having to perform
|
---|
| 389 | square roots when determining the lod. This method allows you to provide a
|
---|
| 390 | squared length depth value to avoid having to do your own square roots.
|
---|
| 391 | */
|
---|
| 392 | ushort getLodIndexSquaredDepth(Real squaredDepth) const;
|
---|
| 393 |
|
---|
| 394 | /** Returns true if this mesh is using manual LOD.
|
---|
| 395 | @remarks
|
---|
| 396 | A mesh can either use automatically generated LOD, or it can use alternative
|
---|
| 397 | meshes as provided by an artist. A mesh can only use either all manual LODs
|
---|
| 398 | or all generated LODs, not a mixture of both.
|
---|
| 399 | */
|
---|
| 400 | bool isLodManual(void) const { return mIsLodManual; }
|
---|
| 401 |
|
---|
| 402 | /** Internal methods for loading LOD, do not use. */
|
---|
| 403 | void _setLodInfo(unsigned short numLevels, bool isManual);
|
---|
| 404 | /** Internal methods for loading LOD, do not use. */
|
---|
| 405 | void _setLodUsage(unsigned short level, MeshLodUsage& usage);
|
---|
| 406 | /** Internal methods for loading LOD, do not use. */
|
---|
| 407 | void _setSubMeshLodFaceList(unsigned short subIdx, unsigned short level, IndexData* facedata);
|
---|
| 408 |
|
---|
| 409 | /** Removes all LOD data from this Mesh. */
|
---|
| 410 | void removeLodLevels(void);
|
---|
| 411 |
|
---|
| 412 | /** Sets the policy for the vertex buffers to be used when loading
|
---|
| 413 | this Mesh.
|
---|
| 414 | @remarks
|
---|
| 415 | By default, when loading the Mesh, static, write-only vertex and index buffers
|
---|
| 416 | will be used where possible in order to improve rendering performance.
|
---|
| 417 | However, such buffers
|
---|
| 418 | cannot be manipulated on the fly by CPU code (although shader code can). If you
|
---|
| 419 | wish to use the CPU to modify these buffers, you should call this method. Note,
|
---|
| 420 | however, that it only takes effect after the Mesh has been reloaded. Note that you
|
---|
| 421 | still have the option of manually repacing the buffers in this mesh with your
|
---|
| 422 | own if you see fit too, in which case you don't need to call this method since it
|
---|
| 423 | only affects buffers created by the mesh itself.
|
---|
| 424 | @par
|
---|
| 425 | You can define the approach to a Mesh by changing the default parameters to
|
---|
| 426 | MeshManager::load if you wish; this means the Mesh is loaded with those options
|
---|
| 427 | the first time instead of you having to reload the mesh after changing these options.
|
---|
| 428 | @param usage The usage flags, which by default are
|
---|
| 429 | HardwareBuffer::HBU_STATIC_WRITE_ONLY
|
---|
| 430 | @param shadowBuffer If set to true, the vertex buffers will be created with a
|
---|
| 431 | system memory shadow buffer. You should set this if you want to be able to
|
---|
| 432 | read from the buffer, because reading from a hardware buffer is a no-no.
|
---|
| 433 | */
|
---|
| 434 | void setVertexBufferPolicy(HardwareBuffer::Usage usage, bool shadowBuffer = false);
|
---|
| 435 | /** Sets the policy for the index buffers to be used when loading
|
---|
| 436 | this Mesh.
|
---|
| 437 | @remarks
|
---|
| 438 | By default, when loading the Mesh, static, write-only vertex and index buffers
|
---|
| 439 | will be used where possible in order to improve rendering performance.
|
---|
| 440 | However, such buffers
|
---|
| 441 | cannot be manipulated on the fly by CPU code (although shader code can). If you
|
---|
| 442 | wish to use the CPU to modify these buffers, you should call this method. Note,
|
---|
| 443 | however, that it only takes effect after the Mesh has been reloaded. Note that you
|
---|
| 444 | still have the option of manually repacing the buffers in this mesh with your
|
---|
| 445 | own if you see fit too, in which case you don't need to call this method since it
|
---|
| 446 | only affects buffers created by the mesh itself.
|
---|
| 447 | @par
|
---|
| 448 | You can define the approach to a Mesh by changing the default parameters to
|
---|
| 449 | MeshManager::load if you wish; this means the Mesh is loaded with those options
|
---|
| 450 | the first time instead of you having to reload the mesh after changing these options.
|
---|
| 451 | @param usage The usage flags, which by default are
|
---|
| 452 | HardwareBuffer::HBU_STATIC_WRITE_ONLY
|
---|
| 453 | @param shadowBuffer If set to true, the index buffers will be created with a
|
---|
| 454 | system memory shadow buffer. You should set this if you want to be able to
|
---|
| 455 | read from the buffer, because reading from a hardware buffer is a no-no.
|
---|
| 456 | */
|
---|
| 457 | void setIndexBufferPolicy(HardwareBuffer::Usage usage, bool shadowBuffer = false);
|
---|
| 458 | /** Gets the usage setting for this meshes vertex buffers. */
|
---|
| 459 | HardwareBuffer::Usage getVertexBufferUsage(void) const { return mVertexBufferUsage; }
|
---|
| 460 | /** Gets the usage setting for this meshes index buffers. */
|
---|
| 461 | HardwareBuffer::Usage getIndexBufferUsage(void) const { return mIndexBufferUsage; }
|
---|
| 462 | /** Gets whether or not this meshes vertex buffers are shadowed. */
|
---|
| 463 | bool isVertexBufferShadowed(void) const { return mVertexBufferShadowBuffer; }
|
---|
| 464 | /** Gets whether or not this meshes index buffers are shadowed. */
|
---|
| 465 | bool isIndexBufferShadowed(void) const { return mIndexBufferShadowBuffer; }
|
---|
| 466 |
|
---|
| 467 |
|
---|
| 468 | /** Rationalises the passed in bone assignment list.
|
---|
| 469 | @remarks
|
---|
| 470 | OGRE supports up to 4 bone assignments per vertex. The reason for this limit
|
---|
| 471 | is that this is the maximum number of assignments that can be passed into
|
---|
| 472 | a hardware-assisted blending algorithm. This method identifies where there are
|
---|
| 473 | more than 4 bone assignments for a given vertex, and eliminates the bone
|
---|
| 474 | assignments with the lowest weights to reduce to this limit. The remaining
|
---|
| 475 | weights are then re-balanced to ensure that they sum to 1.0.
|
---|
| 476 | @param vertexCount The number of vertices.
|
---|
| 477 | @param assignments The bone assignment list to rationalise. This list will be modified and
|
---|
| 478 | entries will be removed where the limits are exceeded.
|
---|
| 479 | @returns The maximum number of bone assignments per vertex found, clamped to [1-4]
|
---|
| 480 | */
|
---|
| 481 | unsigned short _rationaliseBoneAssignments(size_t vertexCount, VertexBoneAssignmentList& assignments);
|
---|
| 482 |
|
---|
| 483 | /** Internal method, be called once to compile bone assignments into geometry buffer.
|
---|
| 484 | @remarks
|
---|
| 485 | The OGRE engine calls this method automatically. It compiles the information
|
---|
| 486 | submitted as bone assignments into a format usable in realtime. It also
|
---|
| 487 | eliminates excessive bone assignments (max is OGRE_MAX_BLEND_WEIGHTS)
|
---|
| 488 | and re-normalises the remaining assignments.
|
---|
| 489 | */
|
---|
| 490 | void _compileBoneAssignments(void);
|
---|
| 491 |
|
---|
| 492 | /** This method builds a set of tangent vectors for a given mesh into a 3D texture coordinate buffer.
|
---|
| 493 | @remarks
|
---|
| 494 | Tangent vectors are vectors representing the local 'X' axis for a given vertex based
|
---|
| 495 | on the orientation of the 2D texture on the geometry. They are built from a combination
|
---|
| 496 | of existing normals, and from the 2D texture coordinates already baked into the model.
|
---|
| 497 | They can be used for a number of things, but most of all they are useful for
|
---|
| 498 | vertex and fragment programs, when you wish to arrive at a common space for doing
|
---|
| 499 | per-pixel calculations.
|
---|
| 500 | @par
|
---|
| 501 | The prerequisites for calling this method include that the vertex data used by every
|
---|
| 502 | SubMesh has both vertex normals and 2D texture coordinates.
|
---|
| 503 | @param sourceTexCoordSet The texture coordinate index which should be used as the source
|
---|
| 504 | of 2D texture coordinates, with which to calculate the tangents.
|
---|
| 505 | @param destTexCoordSet The texture coordinate set which should be used to store the 3D
|
---|
| 506 | coordinates representing a tangent vector per vertex. If this already exists, it
|
---|
| 507 | will be overwritten.
|
---|
| 508 | */
|
---|
| 509 | void buildTangentVectors(unsigned short sourceTexCoordSet = 0, unsigned short destTexCoordSet = 1);
|
---|
| 510 |
|
---|
| 511 | /** Ask the mesh to suggest parameters to a future buildTangentVectors call.
|
---|
| 512 | @remarks
|
---|
| 513 | This helper method will suggest source and destination texture coordinate sets
|
---|
| 514 | for a call to buildTangentVectors. It will detect when there are inappropriate
|
---|
| 515 | conditions (such as multiple geometry sets which don't agree).
|
---|
| 516 | Moreover, it will return 'true' if it detects that there are aleady 3D
|
---|
| 517 | coordinates in the mesh, and therefore tangents may have been prepared already.
|
---|
| 518 | @param outSourceCoordSet Reference to a source texture coordinate set which
|
---|
| 519 | will be populated
|
---|
| 520 | @param outDestCoordSet Reference to a destination texture coordinate set which
|
---|
| 521 | will be populated
|
---|
| 522 | */
|
---|
| 523 | bool suggestTangentVectorBuildParams(unsigned short& outSourceCoordSet, unsigned short& outDestCoordSet);
|
---|
| 524 |
|
---|
| 525 | /** Builds an edge list for this mesh, which can be used for generating a shadow volume
|
---|
| 526 | among other things.
|
---|
| 527 | */
|
---|
| 528 | void buildEdgeList(void);
|
---|
| 529 | /** Destroys and frees the edge lists this mesh has built. */
|
---|
| 530 | void freeEdgeList(void);
|
---|
| 531 |
|
---|
| 532 | /** This method prepares the mesh for generating a renderable shadow volume.
|
---|
| 533 | @remarks
|
---|
| 534 | Preparing a mesh to generate a shadow volume involves firstly ensuring that the
|
---|
| 535 | vertex buffer containing the positions for the mesh is a standalone vertex buffer,
|
---|
| 536 | with no other components in it. This method will therefore break apart any existing
|
---|
| 537 | vertex buffers this mesh holds if position is sharing a vertex buffer.
|
---|
| 538 | Secondly, it will double the size of this vertex buffer so that there are 2 copies of
|
---|
| 539 | the position data for the mesh. The first half is used for the original, and the second
|
---|
| 540 | half is used for the 'extruded' version of the mesh. The vertex count of the main
|
---|
| 541 | VertexData used to render the mesh will remain the same though, so as not to add any
|
---|
| 542 | overhead to regular rendering of the object.
|
---|
| 543 | Both copies of the position are required in one buffer because shadow volumes stretch
|
---|
| 544 | from the original mesh to the extruded version.
|
---|
| 545 | @par
|
---|
| 546 | Because shadow volumes are rendered in turn, no additional
|
---|
| 547 | index buffer space is allocated by this method, a shared index buffer allocated by the
|
---|
| 548 | shadow rendering algorithm is used for addressing this extended vertex buffer.
|
---|
| 549 | */
|
---|
| 550 | void prepareForShadowVolume(void);
|
---|
| 551 |
|
---|
| 552 | /** Return the edge list for this mesh, building it if required.
|
---|
| 553 | @remarks
|
---|
| 554 | You must ensure that the Mesh as been prepared for shadow volume
|
---|
| 555 | rendering if you intend to use this information for that purpose.
|
---|
| 556 | @lodIndex The LOD at which to get the edge list, 0 being the highest.
|
---|
| 557 | */
|
---|
| 558 | EdgeData* getEdgeList(unsigned int lodIndex = 0);
|
---|
| 559 |
|
---|
| 560 | /** Return the edge list for this mesh, building it if required.
|
---|
| 561 | @remarks
|
---|
| 562 | You must ensure that the Mesh as been prepared for shadow volume
|
---|
| 563 | rendering if you intend to use this information for that purpose.
|
---|
| 564 | @lodIndex The LOD at which to get the edge list, 0 being the highest.
|
---|
| 565 | */
|
---|
| 566 | const EdgeData* getEdgeList(unsigned int lodIndex = 0) const;
|
---|
| 567 |
|
---|
| 568 | /** Returns whether this mesh has already had it's geometry prepared for use in
|
---|
| 569 | rendering shadow volumes. */
|
---|
| 570 | bool isPreparedForShadowVolumes(void) const { return mPreparedForShadowVolumes; }
|
---|
| 571 |
|
---|
| 572 | /** Returns whether this mesh has an attached edge list. */
|
---|
| 573 | bool isEdgeListBuilt(void) const { return mEdgeListsBuilt; }
|
---|
| 574 |
|
---|
| 575 | /** Performs a software indexed vertex blend, of the kind used for
|
---|
| 576 | skeletal animation although it can be used for other purposes.
|
---|
| 577 | @remarks
|
---|
| 578 | This function is supplied to update vertex data with blends
|
---|
| 579 | done in software, either because no hardware support is available,
|
---|
| 580 | or that you need the results of the blend for some other CPU operations.
|
---|
| 581 | @param sourceVertexData VertexData class containing positions, normals,
|
---|
| 582 | blend indices and blend weights.
|
---|
| 583 | @param targetVertexData VertexData class containing target position
|
---|
| 584 | and normal buffers which will be updated with the blended versions.
|
---|
| 585 | Note that the layout of the source and target position / normal
|
---|
| 586 | buffers must be identical, ie they must use the same buffer indexes
|
---|
| 587 | @param pMatrices Pointer to an array of matrices to be used to blend
|
---|
| 588 | @param blendNormals If true, normals are blended as well as positions
|
---|
| 589 | */
|
---|
| 590 | static void softwareVertexBlend(const VertexData* sourceVertexData,
|
---|
| 591 | const VertexData* targetVertexData, const Matrix4* pMatrices,
|
---|
| 592 | bool blendNormals);
|
---|
| 593 |
|
---|
| 594 | /** Gets a reference to the optional name assignments of the SubMeshes. */
|
---|
| 595 | const SubMeshNameMap& getSubMeshNameMap(void) const { return mSubMeshNameMap; }
|
---|
| 596 |
|
---|
| 597 | /** Sets whether or not this Mesh should automatically build edge lists
|
---|
| 598 | when asked for them, or whether it should never build them if
|
---|
| 599 | they are not already provided.
|
---|
| 600 | @remarks
|
---|
| 601 | This allows you to create meshes which do not have edge lists calculated,
|
---|
| 602 | because you never want to use them. This value defaults to 'true'
|
---|
| 603 | for mesh formats which did not include edge data, and 'false' for
|
---|
| 604 | newer formats, where edge lists are expected to have been generated
|
---|
| 605 | in advance.
|
---|
| 606 | */
|
---|
| 607 | void setAutoBuildEdgeLists(bool autobuild) { mAutoBuildEdgeLists = autobuild; }
|
---|
| 608 | /** Sets whether or not this Mesh should automatically build edge lists
|
---|
| 609 | when asked for them, or whether it should never build them if
|
---|
| 610 | they are not already provided.
|
---|
| 611 | */
|
---|
| 612 | bool getAutoBuildEdgeLists(void) const { return mAutoBuildEdgeLists; }
|
---|
| 613 |
|
---|
| 614 |
|
---|
| 615 | };
|
---|
| 616 |
|
---|
| 617 | /** Specialisation of SharedPtr to allow SharedPtr to be assigned to MeshPtr
|
---|
| 618 | @note Has to be a subclass since we need operator=.
|
---|
| 619 | We could templatise this instead of repeating per Resource subclass,
|
---|
| 620 | except to do so requires a form VC6 does not support i.e.
|
---|
| 621 | ResourceSubclassPtr<T> : public SharedPtr<T>
|
---|
| 622 | */
|
---|
| 623 | class _OgreExport MeshPtr : public SharedPtr<Mesh>
|
---|
| 624 | {
|
---|
| 625 | public:
|
---|
| 626 | MeshPtr() : SharedPtr<Mesh>() {}
|
---|
| 627 | explicit MeshPtr(Mesh* rep) : SharedPtr<Mesh>(rep) {}
|
---|
| 628 | MeshPtr(const MeshPtr& r) : SharedPtr<Mesh>(r) {}
|
---|
| 629 | MeshPtr(const ResourcePtr& r);
|
---|
| 630 | /// Operator used to convert a ResourcePtr to a MeshPtr
|
---|
| 631 | MeshPtr& operator=(const ResourcePtr& r);
|
---|
| 632 | protected:
|
---|
| 633 | /// Override destroy since we need to delete Mesh after fully defined
|
---|
| 634 | void destroy(void);
|
---|
| 635 | };
|
---|
| 636 |
|
---|
| 637 | /** A way of recording the way each LODs is recorded this Mesh. */
|
---|
| 638 | struct MeshLodUsage
|
---|
| 639 | {
|
---|
| 640 | /// squared Z value from which this LOD will apply
|
---|
| 641 | Real fromDepthSquared;
|
---|
| 642 | /// Only relevant if mIsLodManual is true, the name of the alternative mesh to use
|
---|
| 643 | String manualName;
|
---|
| 644 | /// Hard link to mesh to avoid looking up each time
|
---|
| 645 | mutable MeshPtr manualMesh;
|
---|
| 646 | /// Edge list for this LOD level (may be derived from manual mesh)
|
---|
| 647 | mutable EdgeData* edgeData;
|
---|
| 648 | };
|
---|
| 649 |
|
---|
| 650 |
|
---|
| 651 |
|
---|
| 652 | } // namespace
|
---|
| 653 |
|
---|
| 654 | #endif
|
---|