[148] | 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-2013 Torus Knot Software Ltd |
---|
| 8 | |
---|
| 9 | Permission is hereby granted, free of charge, to any person obtaining a copy |
---|
| 10 | of this software and associated documentation files (the "Software"), to deal |
---|
| 11 | in the Software without restriction, including without limitation the rights |
---|
| 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
---|
| 13 | copies of the Software, and to permit persons to whom the Software is |
---|
| 14 | furnished to do so, subject to the following conditions: |
---|
| 15 | |
---|
| 16 | The above copyright notice and this permission notice shall be included in |
---|
| 17 | all copies or substantial portions of the Software. |
---|
| 18 | |
---|
| 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
---|
| 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
---|
| 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
---|
| 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
---|
| 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
---|
| 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
---|
| 25 | THE SOFTWARE. |
---|
| 26 | ----------------------------------------------------------------------------- |
---|
| 27 | */ |
---|
| 28 | #ifndef __Mesh_H__ |
---|
| 29 | #define __Mesh_H__ |
---|
| 30 | |
---|
| 31 | #include "OgrePrerequisites.h" |
---|
| 32 | |
---|
| 33 | #include "OgreResource.h" |
---|
| 34 | #include "OgreVertexIndexData.h" |
---|
| 35 | #include "OgreAxisAlignedBox.h" |
---|
| 36 | #include "OgreVertexBoneAssignment.h" |
---|
| 37 | #include "OgreIteratorWrappers.h" |
---|
| 38 | #include "OgreHardwareVertexBuffer.h" |
---|
| 39 | #include "OgreSkeleton.h" |
---|
| 40 | #include "OgreAnimation.h" |
---|
| 41 | #include "OgreAnimationTrack.h" |
---|
| 42 | #include "OgrePose.h" |
---|
| 43 | #include "OgreDataStream.h" |
---|
| 44 | #include "OgreHeaderPrefix.h" |
---|
| 45 | |
---|
| 46 | |
---|
| 47 | namespace Ogre { |
---|
| 48 | |
---|
| 49 | |
---|
| 50 | /** \addtogroup Core |
---|
| 51 | * @{ |
---|
| 52 | */ |
---|
| 53 | /** \addtogroup Resources |
---|
| 54 | * @{ |
---|
| 55 | */ |
---|
| 56 | |
---|
| 57 | struct MeshLodUsage; |
---|
| 58 | struct LodConfig; |
---|
| 59 | class LodStrategy; |
---|
| 60 | |
---|
| 61 | /** Resource holding data about 3D mesh. |
---|
| 62 | @remarks |
---|
| 63 | This class holds the data used to represent a discrete |
---|
| 64 | 3-dimensional object. Mesh data usually contains more |
---|
| 65 | than just vertices and triangle information; it also |
---|
| 66 | includes references to materials (and the faces which use them), |
---|
| 67 | level-of-detail reduction information, convex hull definition, |
---|
| 68 | skeleton/bones information, keyframe animation etc. |
---|
| 69 | However, it is important to note the emphasis on the word |
---|
| 70 | 'discrete' here. This class does not cover the large-scale |
---|
| 71 | sprawling geometry found in level / landscape data. |
---|
| 72 | @par |
---|
| 73 | Multiple world objects can (indeed should) be created from a |
---|
| 74 | single mesh object - see the Entity class for more info. |
---|
| 75 | The mesh object will have it's own default |
---|
| 76 | material properties, but potentially each world instance may |
---|
| 77 | wish to customise the materials from the original. When the object |
---|
| 78 | is instantiated into a scene node, the mesh material properties |
---|
| 79 | will be taken by default but may be changed. These properties |
---|
| 80 | are actually held at the SubMesh level since a single mesh may |
---|
| 81 | have parts with different materials. |
---|
| 82 | @par |
---|
| 83 | As described above, because the mesh may have sections of differing |
---|
| 84 | material properties, a mesh is inherently a compound construct, |
---|
| 85 | consisting of one or more SubMesh objects. |
---|
| 86 | However, it strongly 'owns' it's SubMeshes such that they |
---|
| 87 | are loaded / unloaded at the same time. This is contrary to |
---|
| 88 | the approach taken to hierarchically related (but loosely owned) |
---|
| 89 | scene nodes, where data is loaded / unloaded separately. Note |
---|
| 90 | also that mesh sub-sections (when used in an instantiated object) |
---|
| 91 | share the same scene node as the parent. |
---|
| 92 | */ |
---|
| 93 | class _OgreExport Mesh: public Resource, public AnimationContainer |
---|
| 94 | { |
---|
| 95 | friend class SubMesh; |
---|
| 96 | friend class MeshSerializerImpl; |
---|
| 97 | friend class MeshSerializerImpl_v1_4; |
---|
| 98 | friend class MeshSerializerImpl_v1_2; |
---|
| 99 | friend class MeshSerializerImpl_v1_1; |
---|
| 100 | |
---|
| 101 | public: |
---|
| 102 | typedef vector<Real>::type LodValueList; |
---|
| 103 | typedef vector<MeshLodUsage>::type MeshLodUsageList; |
---|
| 104 | /// Multimap of vertex bone assignments (orders by vertex index). |
---|
| 105 | typedef multimap<size_t, VertexBoneAssignment>::type VertexBoneAssignmentList; |
---|
| 106 | typedef MapIterator<VertexBoneAssignmentList> BoneAssignmentIterator; |
---|
| 107 | typedef vector<SubMesh*>::type SubMeshList; |
---|
| 108 | typedef vector<unsigned short>::type IndexMap; |
---|
| 109 | |
---|
| 110 | protected: |
---|
| 111 | /** A list of submeshes which make up this mesh. |
---|
| 112 | Each mesh is made up of 1 or more submeshes, which |
---|
| 113 | are each based on a single material and can have their |
---|
| 114 | own vertex data (they may not - they can share vertex data |
---|
| 115 | from the Mesh, depending on preference). |
---|
| 116 | */ |
---|
| 117 | SubMeshList mSubMeshList; |
---|
| 118 | |
---|
| 119 | /** Internal method for making the space for a vertex element to hold tangents. */ |
---|
| 120 | void organiseTangentsBuffer(VertexData *vertexData, |
---|
| 121 | VertexElementSemantic targetSemantic, unsigned short index, |
---|
| 122 | unsigned short sourceTexCoordSet); |
---|
| 123 | |
---|
| 124 | public: |
---|
| 125 | /** A hashmap used to store optional SubMesh names. |
---|
| 126 | Translates a name into SubMesh index. |
---|
| 127 | */ |
---|
| 128 | typedef HashMap<String, ushort> SubMeshNameMap ; |
---|
| 129 | |
---|
| 130 | |
---|
| 131 | protected: |
---|
| 132 | |
---|
| 133 | DataStreamPtr mFreshFromDisk; |
---|
| 134 | |
---|
| 135 | SubMeshNameMap mSubMeshNameMap ; |
---|
| 136 | |
---|
| 137 | /// Local bounding box volume. |
---|
| 138 | AxisAlignedBox mAABB; |
---|
| 139 | /// Local bounding sphere radius (centered on object). |
---|
| 140 | Real mBoundRadius; |
---|
| 141 | |
---|
| 142 | /// Optional linked skeleton. |
---|
| 143 | String mSkeletonName; |
---|
| 144 | SkeletonPtr mSkeleton; |
---|
| 145 | |
---|
| 146 | |
---|
| 147 | VertexBoneAssignmentList mBoneAssignments; |
---|
| 148 | |
---|
| 149 | /// Flag indicating that bone assignments need to be recompiled. |
---|
| 150 | bool mBoneAssignmentsOutOfDate; |
---|
| 151 | |
---|
| 152 | /** Build the index map between bone index and blend index. */ |
---|
| 153 | void buildIndexMap(const VertexBoneAssignmentList& boneAssignments, |
---|
| 154 | IndexMap& boneIndexToBlendIndexMap, IndexMap& blendIndexToBoneIndexMap); |
---|
| 155 | /** Compile bone assignments into blend index and weight buffers. */ |
---|
| 156 | void compileBoneAssignments(const VertexBoneAssignmentList& boneAssignments, |
---|
| 157 | unsigned short numBlendWeightsPerVertex, |
---|
| 158 | IndexMap& blendIndexToBoneIndexMap, |
---|
| 159 | VertexData* targetVertexData); |
---|
| 160 | |
---|
| 161 | const LodStrategy *mLodStrategy; |
---|
| 162 | bool mIsLodManual; |
---|
| 163 | ushort mNumLods; |
---|
| 164 | MeshLodUsageList mMeshLodUsageList; |
---|
| 165 | |
---|
| 166 | HardwareBuffer::Usage mVertexBufferUsage; |
---|
| 167 | HardwareBuffer::Usage mIndexBufferUsage; |
---|
| 168 | bool mVertexBufferShadowBuffer; |
---|
| 169 | bool mIndexBufferShadowBuffer; |
---|
| 170 | |
---|
| 171 | |
---|
| 172 | bool mPreparedForShadowVolumes; |
---|
| 173 | bool mEdgeListsBuilt; |
---|
| 174 | bool mAutoBuildEdgeLists; |
---|
| 175 | |
---|
| 176 | /// Storage of morph animations, lookup by name |
---|
| 177 | typedef map<String, Animation*>::type AnimationList; |
---|
| 178 | AnimationList mAnimationsList; |
---|
| 179 | /// The vertex animation type associated with the shared vertex data |
---|
| 180 | mutable VertexAnimationType mSharedVertexDataAnimationType; |
---|
| 181 | /// Whether vertex animation includes normals |
---|
| 182 | mutable bool mSharedVertexDataAnimationIncludesNormals; |
---|
| 183 | /// Do we need to scan animations for animation types? |
---|
| 184 | mutable bool mAnimationTypesDirty; |
---|
| 185 | |
---|
| 186 | /// List of available poses for shared and dedicated geometryPoseList |
---|
| 187 | PoseList mPoseList; |
---|
| 188 | mutable bool mPosesIncludeNormals; |
---|
| 189 | |
---|
| 190 | |
---|
| 191 | /** Loads the mesh from disk. This call only performs IO, it |
---|
| 192 | does not parse the bytestream or check for any errors therein. |
---|
| 193 | It also does not set up submeshes, etc. You have to call load() |
---|
| 194 | to do that. |
---|
| 195 | */ |
---|
| 196 | void prepareImpl(void); |
---|
| 197 | /** Destroys data cached by prepareImpl. |
---|
| 198 | */ |
---|
| 199 | void unprepareImpl(void); |
---|
| 200 | /// @copydoc Resource::loadImpl |
---|
| 201 | void loadImpl(void); |
---|
| 202 | /// @copydoc Resource::postLoadImpl |
---|
| 203 | void postLoadImpl(void); |
---|
| 204 | /// @copydoc Resource::unloadImpl |
---|
| 205 | void unloadImpl(void); |
---|
| 206 | /// @copydoc Resource::calculateSize |
---|
| 207 | size_t calculateSize(void) const; |
---|
| 208 | |
---|
| 209 | void mergeAdjacentTexcoords( unsigned short finalTexCoordSet, |
---|
| 210 | unsigned short texCoordSetToDestroy, VertexData *vertexData ); |
---|
| 211 | |
---|
| 212 | |
---|
| 213 | public: |
---|
| 214 | /** Default constructor - used by MeshManager |
---|
| 215 | @warning |
---|
| 216 | Do not call this method directly. |
---|
| 217 | */ |
---|
| 218 | Mesh(ResourceManager* creator, const String& name, ResourceHandle handle, |
---|
| 219 | const String& group, bool isManual = false, ManualResourceLoader* loader = 0); |
---|
| 220 | ~Mesh(); |
---|
| 221 | |
---|
| 222 | // NB All methods below are non-virtual since they will be |
---|
| 223 | // called in the rendering loop - speed is of the essence. |
---|
| 224 | |
---|
| 225 | /** Creates a new SubMesh. |
---|
| 226 | @remarks |
---|
| 227 | Method for manually creating geometry for the mesh. |
---|
| 228 | Note - use with extreme caution - you must be sure that |
---|
| 229 | you have set up the geometry properly. |
---|
| 230 | */ |
---|
| 231 | SubMesh* createSubMesh(void); |
---|
| 232 | |
---|
| 233 | /** Creates a new SubMesh and gives it a name |
---|
| 234 | */ |
---|
| 235 | SubMesh* createSubMesh(const String& name); |
---|
| 236 | |
---|
| 237 | /** Gives a name to a SubMesh |
---|
| 238 | */ |
---|
| 239 | void nameSubMesh(const String& name, ushort index); |
---|
| 240 | |
---|
| 241 | /** Removes a name from a SubMesh |
---|
| 242 | */ |
---|
| 243 | void unnameSubMesh(const String& name); |
---|
| 244 | |
---|
| 245 | /** Gets the index of a submesh with a given name. |
---|
| 246 | @remarks |
---|
| 247 | Useful if you identify the SubMeshes by name (using nameSubMesh) |
---|
| 248 | but wish to have faster repeat access. |
---|
| 249 | */ |
---|
| 250 | ushort _getSubMeshIndex(const String& name) const; |
---|
| 251 | |
---|
| 252 | /** Gets the number of sub meshes which comprise this mesh. |
---|
| 253 | */ |
---|
| 254 | unsigned short getNumSubMeshes(void) const; |
---|
| 255 | |
---|
| 256 | /** Gets a pointer to the submesh indicated by the index. |
---|
| 257 | */ |
---|
| 258 | SubMesh* getSubMesh(unsigned short index) const; |
---|
| 259 | |
---|
| 260 | /** Gets a SubMesh by name |
---|
| 261 | */ |
---|
| 262 | SubMesh* getSubMesh(const String& name) const ; |
---|
| 263 | |
---|
| 264 | /** Destroy a SubMesh with the given index. |
---|
| 265 | @note |
---|
| 266 | This will invalidate the contents of any existing Entity, or |
---|
| 267 | any other object that is referring to the SubMesh list. Entity will |
---|
| 268 | detect this and reinitialise, but it is still a disruptive action. |
---|
| 269 | */ |
---|
| 270 | void destroySubMesh(unsigned short index); |
---|
| 271 | |
---|
| 272 | /** Destroy a SubMesh with the given name. |
---|
| 273 | @note |
---|
| 274 | This will invalidate the contents of any existing Entity, or |
---|
| 275 | any other object that is referring to the SubMesh list. Entity will |
---|
| 276 | detect this and reinitialise, but it is still a disruptive action. |
---|
| 277 | */ |
---|
| 278 | void destroySubMesh(const String& name); |
---|
| 279 | |
---|
| 280 | typedef VectorIterator<SubMeshList> SubMeshIterator; |
---|
| 281 | /// Gets an iterator over the available submeshes |
---|
| 282 | SubMeshIterator getSubMeshIterator(void) |
---|
| 283 | { return SubMeshIterator(mSubMeshList.begin(), mSubMeshList.end()); } |
---|
| 284 | |
---|
| 285 | /** Shared vertex data. |
---|
| 286 | @remarks |
---|
| 287 | This vertex data can be shared among multiple submeshes. SubMeshes may not have |
---|
| 288 | their own VertexData, they may share this one. |
---|
| 289 | @par |
---|
| 290 | The use of shared or non-shared buffers is determined when |
---|
| 291 | model data is converted to the OGRE .mesh format. |
---|
| 292 | */ |
---|
| 293 | VertexData *sharedVertexData; |
---|
| 294 | |
---|
| 295 | /** Shared index map for translating blend index to bone index. |
---|
| 296 | @remarks |
---|
| 297 | This index map can be shared among multiple submeshes. SubMeshes might not have |
---|
| 298 | their own IndexMap, they might share this one. |
---|
| 299 | @par |
---|
| 300 | We collect actually used bones of all bone assignments, and build the |
---|
| 301 | blend index in 'packed' form, then the range of the blend index in vertex |
---|
| 302 | data VES_BLEND_INDICES element is continuous, with no gaps. Thus, by |
---|
| 303 | minimising the world matrix array constants passing to GPU, we can support |
---|
| 304 | more bones for a mesh when hardware skinning is used. The hardware skinning |
---|
| 305 | support limit is applied to each set of vertex data in the mesh, in other words, the |
---|
| 306 | hardware skinning support limit is applied only to the actually used bones of each |
---|
| 307 | SubMeshes, not all bones across the entire Mesh. |
---|
| 308 | @par |
---|
| 309 | Because the blend index is different to the bone index, therefore, we use |
---|
| 310 | the index map to translate the blend index to bone index. |
---|
| 311 | @par |
---|
| 312 | The use of shared or non-shared index map is determined when |
---|
| 313 | model data is converted to the OGRE .mesh format. |
---|
| 314 | */ |
---|
| 315 | IndexMap sharedBlendIndexToBoneIndexMap; |
---|
| 316 | |
---|
| 317 | /** Makes a copy of this mesh object and gives it a new name. |
---|
| 318 | @remarks |
---|
| 319 | This is useful if you want to tweak an existing mesh without affecting the original one. The |
---|
| 320 | newly cloned mesh is registered with the MeshManager under the new name. |
---|
| 321 | @param newName |
---|
| 322 | The name to give the clone. |
---|
| 323 | @param newGroup |
---|
| 324 | Optional name of the new group to assign the clone to; |
---|
| 325 | if you leave this blank, the clone will be assigned to the same |
---|
| 326 | group as this Mesh. |
---|
| 327 | */ |
---|
| 328 | MeshPtr clone(const String& newName, const String& newGroup = StringUtil::BLANK); |
---|
| 329 | |
---|
| 330 | /** Get the axis-aligned bounding box for this mesh. |
---|
| 331 | */ |
---|
| 332 | const AxisAlignedBox& getBounds(void) const; |
---|
| 333 | |
---|
| 334 | /** Gets the radius of the bounding sphere surrounding this mesh. */ |
---|
| 335 | Real getBoundingSphereRadius(void) const; |
---|
| 336 | |
---|
| 337 | /** Manually set the bounding box for this Mesh. |
---|
| 338 | @remarks |
---|
| 339 | Calling this method is required when building manual meshes now, because OGRE can no longer |
---|
| 340 | update the bounds for you, because it cannot necessarily read vertex data back from |
---|
| 341 | the vertex buffers which this mesh uses (they very well might be write-only, and even |
---|
| 342 | if they are not, reading data from a hardware buffer is a bottleneck). |
---|
| 343 | @param pad If true, a certain padding will be added to the bounding box to separate it from the mesh |
---|
| 344 | */ |
---|
| 345 | void _setBounds(const AxisAlignedBox& bounds, bool pad = true); |
---|
| 346 | |
---|
| 347 | /** Manually set the bounding radius. |
---|
| 348 | @remarks |
---|
| 349 | Calling this method is required when building manual meshes now, because OGRE can no longer |
---|
| 350 | update the bounds for you, because it cannot necessarily read vertex data back from |
---|
| 351 | the vertex buffers which this mesh uses (they very well might be write-only, and even |
---|
| 352 | if they are not, reading data from a hardware buffer is a bottleneck). |
---|
| 353 | */ |
---|
| 354 | void _setBoundingSphereRadius(Real radius); |
---|
| 355 | |
---|
| 356 | /** Sets the name of the skeleton this Mesh uses for animation. |
---|
| 357 | @remarks |
---|
| 358 | Meshes can optionally be assigned a skeleton which can be used to animate |
---|
| 359 | the mesh through bone assignments. The default is for the Mesh to use no |
---|
| 360 | skeleton. Calling this method with a valid skeleton filename will cause the |
---|
| 361 | skeleton to be loaded if it is not already (a single skeleton can be shared |
---|
| 362 | by many Mesh objects). |
---|
| 363 | @param skelName |
---|
| 364 | The name of the .skeleton file to use, or an empty string to use |
---|
| 365 | no skeleton |
---|
| 366 | */ |
---|
| 367 | void setSkeletonName(const String& skelName); |
---|
| 368 | |
---|
| 369 | /** Returns true if this Mesh has a linked Skeleton. */ |
---|
| 370 | bool hasSkeleton(void) const; |
---|
| 371 | |
---|
| 372 | /** Returns whether or not this mesh has some kind of vertex animation. |
---|
| 373 | */ |
---|
| 374 | bool hasVertexAnimation(void) const; |
---|
| 375 | |
---|
| 376 | /** Gets a pointer to any linked Skeleton. |
---|
| 377 | @return |
---|
| 378 | Weak reference to the skeleton - copy this if you want to hold a strong pointer. |
---|
| 379 | */ |
---|
| 380 | const SkeletonPtr& getSkeleton(void) const; |
---|
| 381 | |
---|
| 382 | /** Gets the name of any linked Skeleton */ |
---|
| 383 | const String& getSkeletonName(void) const; |
---|
| 384 | /** Initialise an animation set suitable for use with this mesh. |
---|
| 385 | @remarks |
---|
| 386 | Only recommended for use inside the engine, not by applications. |
---|
| 387 | */ |
---|
| 388 | void _initAnimationState(AnimationStateSet* animSet); |
---|
| 389 | |
---|
| 390 | /** Refresh an animation set suitable for use with this mesh. |
---|
| 391 | @remarks |
---|
| 392 | Only recommended for use inside the engine, not by applications. |
---|
| 393 | */ |
---|
| 394 | void _refreshAnimationState(AnimationStateSet* animSet); |
---|
| 395 | /** Assigns a vertex to a bone with a given weight, for skeletal animation. |
---|
| 396 | @remarks |
---|
| 397 | This method is only valid after calling setSkeletonName. |
---|
| 398 | Since this is a one-off process there exists only 'addBoneAssignment' and |
---|
| 399 | 'clearBoneAssignments' methods, no 'editBoneAssignment'. You should not need |
---|
| 400 | to modify bone assignments during rendering (only the positions of bones) and OGRE |
---|
| 401 | reserves the right to do some internal data reformatting of this information, depending |
---|
| 402 | on render system requirements. |
---|
| 403 | @par |
---|
| 404 | This method is for assigning weights to the shared geometry of the Mesh. To assign |
---|
| 405 | weights to the per-SubMesh geometry, see the equivalent methods on SubMesh. |
---|
| 406 | */ |
---|
| 407 | void addBoneAssignment(const VertexBoneAssignment& vertBoneAssign); |
---|
| 408 | |
---|
| 409 | /** Removes all bone assignments for this mesh. |
---|
| 410 | @remarks |
---|
| 411 | This method is for modifying weights to the shared geometry of the Mesh. To assign |
---|
| 412 | weights to the per-SubMesh geometry, see the equivalent methods on SubMesh. |
---|
| 413 | */ |
---|
| 414 | void clearBoneAssignments(void); |
---|
| 415 | |
---|
| 416 | /** Internal notification, used to tell the Mesh which Skeleton to use without loading it. |
---|
| 417 | @remarks |
---|
| 418 | This is only here for unusual situation where you want to manually set up a |
---|
| 419 | Skeleton. Best to let OGRE deal with this, don't call it yourself unless you |
---|
| 420 | really know what you're doing. |
---|
| 421 | */ |
---|
| 422 | void _notifySkeleton(SkeletonPtr& pSkel); |
---|
| 423 | |
---|
| 424 | |
---|
| 425 | /** Gets an iterator for access all bone assignments. |
---|
| 426 | */ |
---|
| 427 | BoneAssignmentIterator getBoneAssignmentIterator(void); |
---|
| 428 | |
---|
| 429 | /** Gets a const reference to the list of bone assignments |
---|
| 430 | */ |
---|
| 431 | const VertexBoneAssignmentList& getBoneAssignments() const { return mBoneAssignments; } |
---|
| 432 | |
---|
| 433 | |
---|
| 434 | /** Returns the number of levels of detail that this mesh supports. |
---|
| 435 | @remarks |
---|
| 436 | This number includes the original model. |
---|
| 437 | */ |
---|
| 438 | ushort getNumLodLevels(void) const; |
---|
| 439 | /** Gets details of the numbered level of detail entry. */ |
---|
| 440 | const MeshLodUsage& getLodLevel(ushort index) const; |
---|
| 441 | /** Adds a new manual level-of-detail entry to this Mesh. |
---|
| 442 | @remarks |
---|
| 443 | As an alternative to generating lower level of detail versions of a mesh, you can |
---|
| 444 | use your own manually modelled meshes as lower level versions. This lets you |
---|
| 445 | have complete control over the LOD, and in addition lets you scale down other |
---|
| 446 | aspects of the model which cannot be done using the generated method; for example, |
---|
| 447 | you could use less detailed materials and / or use less bones in the skeleton if |
---|
| 448 | this is an animated mesh. Therefore for complex models you are likely to be better off |
---|
| 449 | modelling your LODs yourself and using this method, whilst for models with fairly |
---|
| 450 | simple materials and no animation you can just use the generateLodLevels method. |
---|
| 451 | @param value |
---|
| 452 | The value from which this LOD will apply. |
---|
| 453 | @param meshName |
---|
| 454 | The name of the mesh which will be the lower level detail version. |
---|
| 455 | */ |
---|
| 456 | void createManualLodLevel(Real value, const String& meshName, const String& groupName = Ogre::String()); |
---|
| 457 | |
---|
| 458 | /** Changes the alternate mesh to use as a manual LOD at the given index. |
---|
| 459 | @remarks |
---|
| 460 | Note that the index of a LOD may change if you insert other LODs. If in doubt, |
---|
| 461 | use getLodIndex(). |
---|
| 462 | @param index |
---|
| 463 | The index of the level to be changed. |
---|
| 464 | @param meshName |
---|
| 465 | The name of the mesh which will be the lower level detail version. |
---|
| 466 | */ |
---|
| 467 | void updateManualLodLevel(ushort index, const String& meshName); |
---|
| 468 | |
---|
| 469 | /** Retrieves the level of detail index for the given LOD value. |
---|
| 470 | @note |
---|
| 471 | The value passed in is the 'transformed' value. If you are dealing with |
---|
| 472 | an original source value (e.g. distance), use LodStrategy::transformUserValue |
---|
| 473 | to turn this into a lookup value. |
---|
| 474 | */ |
---|
| 475 | ushort getLodIndex(Real value) const; |
---|
| 476 | |
---|
| 477 | /** Returns true if this mesh is using manual LOD. |
---|
| 478 | @remarks |
---|
| 479 | A mesh can either use automatically generated LOD, or it can use alternative |
---|
| 480 | meshes as provided by an artist. A mesh can only use either all manual LODs |
---|
| 481 | or all generated LODs, not a mixture of both. |
---|
| 482 | */ |
---|
| 483 | bool isLodManual(void) const { return mIsLodManual; } |
---|
| 484 | |
---|
| 485 | /** Internal methods for loading LOD, do not use. */ |
---|
| 486 | void _setLodInfo(unsigned short numLevels, bool isManual); |
---|
| 487 | /** Internal methods for loading LOD, do not use. */ |
---|
| 488 | void _setLodUsage(unsigned short level, MeshLodUsage& usage); |
---|
| 489 | /** Internal methods for loading LOD, do not use. */ |
---|
| 490 | void _setSubMeshLodFaceList(unsigned short subIdx, unsigned short level, IndexData* facedata); |
---|
| 491 | |
---|
| 492 | /** Removes all LOD data from this Mesh. */ |
---|
| 493 | void removeLodLevels(void); |
---|
| 494 | |
---|
| 495 | /** Sets the policy for the vertex buffers to be used when loading |
---|
| 496 | this Mesh. |
---|
| 497 | @remarks |
---|
| 498 | By default, when loading the Mesh, static, write-only vertex and index buffers |
---|
| 499 | will be used where possible in order to improve rendering performance. |
---|
| 500 | However, such buffers |
---|
| 501 | cannot be manipulated on the fly by CPU code (although shader code can). If you |
---|
| 502 | wish to use the CPU to modify these buffers, you should call this method. Note, |
---|
| 503 | however, that it only takes effect after the Mesh has been reloaded. Note that you |
---|
| 504 | still have the option of manually repacing the buffers in this mesh with your |
---|
| 505 | own if you see fit too, in which case you don't need to call this method since it |
---|
| 506 | only affects buffers created by the mesh itself. |
---|
| 507 | @par |
---|
| 508 | You can define the approach to a Mesh by changing the default parameters to |
---|
| 509 | MeshManager::load if you wish; this means the Mesh is loaded with those options |
---|
| 510 | the first time instead of you having to reload the mesh after changing these options. |
---|
| 511 | @param usage |
---|
| 512 | The usage flags, which by default are |
---|
| 513 | HardwareBuffer::HBU_STATIC_WRITE_ONLY |
---|
| 514 | @param shadowBuffer |
---|
| 515 | If set to @c true, the vertex buffers will be created with a |
---|
| 516 | system memory shadow buffer. You should set this if you want to be able to |
---|
| 517 | read from the buffer, because reading from a hardware buffer is a no-no. |
---|
| 518 | */ |
---|
| 519 | void setVertexBufferPolicy(HardwareBuffer::Usage usage, bool shadowBuffer = false); |
---|
| 520 | /** Sets the policy for the index buffers to be used when loading |
---|
| 521 | this Mesh. |
---|
| 522 | @remarks |
---|
| 523 | By default, when loading the Mesh, static, write-only vertex and index buffers |
---|
| 524 | will be used where possible in order to improve rendering performance. |
---|
| 525 | However, such buffers |
---|
| 526 | cannot be manipulated on the fly by CPU code (although shader code can). If you |
---|
| 527 | wish to use the CPU to modify these buffers, you should call this method. Note, |
---|
| 528 | however, that it only takes effect after the Mesh has been reloaded. Note that you |
---|
| 529 | still have the option of manually repacing the buffers in this mesh with your |
---|
| 530 | own if you see fit too, in which case you don't need to call this method since it |
---|
| 531 | only affects buffers created by the mesh itself. |
---|
| 532 | @par |
---|
| 533 | You can define the approach to a Mesh by changing the default parameters to |
---|
| 534 | MeshManager::load if you wish; this means the Mesh is loaded with those options |
---|
| 535 | the first time instead of you having to reload the mesh after changing these options. |
---|
| 536 | @param usage |
---|
| 537 | The usage flags, which by default are |
---|
| 538 | HardwareBuffer::HBU_STATIC_WRITE_ONLY |
---|
| 539 | @param shadowBuffer |
---|
| 540 | If set to @c true, the index buffers will be created with a |
---|
| 541 | system memory shadow buffer. You should set this if you want to be able to |
---|
| 542 | read from the buffer, because reading from a hardware buffer is a no-no. |
---|
| 543 | */ |
---|
| 544 | void setIndexBufferPolicy(HardwareBuffer::Usage usage, bool shadowBuffer = false); |
---|
| 545 | /** Gets the usage setting for this meshes vertex buffers. */ |
---|
| 546 | HardwareBuffer::Usage getVertexBufferUsage(void) const { return mVertexBufferUsage; } |
---|
| 547 | /** Gets the usage setting for this meshes index buffers. */ |
---|
| 548 | HardwareBuffer::Usage getIndexBufferUsage(void) const { return mIndexBufferUsage; } |
---|
| 549 | /** Gets whether or not this meshes vertex buffers are shadowed. */ |
---|
| 550 | bool isVertexBufferShadowed(void) const { return mVertexBufferShadowBuffer; } |
---|
| 551 | /** Gets whether or not this meshes index buffers are shadowed. */ |
---|
| 552 | bool isIndexBufferShadowed(void) const { return mIndexBufferShadowBuffer; } |
---|
| 553 | |
---|
| 554 | |
---|
| 555 | /** Rationalises the passed in bone assignment list. |
---|
| 556 | @remarks |
---|
| 557 | OGRE supports up to 4 bone assignments per vertex. The reason for this limit |
---|
| 558 | is that this is the maximum number of assignments that can be passed into |
---|
| 559 | a hardware-assisted blending algorithm. This method identifies where there are |
---|
| 560 | more than 4 bone assignments for a given vertex, and eliminates the bone |
---|
| 561 | assignments with the lowest weights to reduce to this limit. The remaining |
---|
| 562 | weights are then re-balanced to ensure that they sum to 1.0. |
---|
| 563 | @param vertexCount |
---|
| 564 | The number of vertices. |
---|
| 565 | @param assignments |
---|
| 566 | The bone assignment list to rationalise. This list will be modified and |
---|
| 567 | entries will be removed where the limits are exceeded. |
---|
| 568 | @return |
---|
| 569 | The maximum number of bone assignments per vertex found, clamped to [1-4] |
---|
| 570 | */ |
---|
| 571 | unsigned short _rationaliseBoneAssignments(size_t vertexCount, VertexBoneAssignmentList& assignments); |
---|
| 572 | |
---|
| 573 | /** Internal method, be called once to compile bone assignments into geometry buffer. |
---|
| 574 | @remarks |
---|
| 575 | The OGRE engine calls this method automatically. It compiles the information |
---|
| 576 | submitted as bone assignments into a format usable in realtime. It also |
---|
| 577 | eliminates excessive bone assignments (max is OGRE_MAX_BLEND_WEIGHTS) |
---|
| 578 | and re-normalises the remaining assignments. |
---|
| 579 | */ |
---|
| 580 | void _compileBoneAssignments(void); |
---|
| 581 | |
---|
| 582 | /** Internal method, be called once to update the compiled bone assignments. |
---|
| 583 | @remarks |
---|
| 584 | The OGRE engine calls this method automatically. It updates the compiled bone |
---|
| 585 | assignments if requested. |
---|
| 586 | */ |
---|
| 587 | void _updateCompiledBoneAssignments(void); |
---|
| 588 | |
---|
| 589 | /** This method collapses two texcoords into one for all submeshes where this is possible. |
---|
| 590 | @remarks |
---|
| 591 | Often a submesh can have two tex. coords. (i.e. TEXCOORD0 & TEXCOORD1), being both |
---|
| 592 | composed of two floats. There are many practical reasons why it would be more convenient |
---|
| 593 | to merge both of them into one TEXCOORD0 of 4 floats. This function does exactly that |
---|
| 594 | The finalTexCoordSet must have enough space for the merge, or else the submesh will be |
---|
| 595 | skipped. (i.e. you can't merge a tex. coord with 3 floats with one having 2 floats) |
---|
| 596 | |
---|
| 597 | finalTexCoordSet & texCoordSetToDestroy must be in the same buffer source, and must |
---|
| 598 | be adjacent. |
---|
| 599 | @param finalTexCoordSet The tex. coord index to merge to. Should have enough space to |
---|
| 600 | actually work. |
---|
| 601 | @param texCoordSetToDestroy The texture coordinate index that will disappear on |
---|
| 602 | successful merges. |
---|
| 603 | */ |
---|
| 604 | void mergeAdjacentTexcoords( unsigned short finalTexCoordSet, unsigned short texCoordSetToDestroy ); |
---|
| 605 | |
---|
| 606 | void _configureMeshLodUsage(const LodConfig& lodConfig); |
---|
| 607 | |
---|
| 608 | /** This method builds a set of tangent vectors for a given mesh into a 3D texture coordinate buffer. |
---|
| 609 | @remarks |
---|
| 610 | Tangent vectors are vectors representing the local 'X' axis for a given vertex based |
---|
| 611 | on the orientation of the 2D texture on the geometry. They are built from a combination |
---|
| 612 | of existing normals, and from the 2D texture coordinates already baked into the model. |
---|
| 613 | They can be used for a number of things, but most of all they are useful for |
---|
| 614 | vertex and fragment programs, when you wish to arrive at a common space for doing |
---|
| 615 | per-pixel calculations. |
---|
| 616 | @par |
---|
| 617 | The prerequisites for calling this method include that the vertex data used by every |
---|
| 618 | SubMesh has both vertex normals and 2D texture coordinates. |
---|
| 619 | @param targetSemantic |
---|
| 620 | The semantic to store the tangents in. Defaults to |
---|
| 621 | the explicit tangent binding, but note that this is only usable on more |
---|
| 622 | modern hardware (Shader Model 2), so if you need portability with older |
---|
| 623 | cards you should change this to a texture coordinate binding instead. |
---|
| 624 | @param sourceTexCoordSet |
---|
| 625 | The texture coordinate index which should be used as the source |
---|
| 626 | of 2D texture coordinates, with which to calculate the tangents. |
---|
| 627 | @param index |
---|
| 628 | The element index, ie the texture coordinate set which should be used to store the 3D |
---|
| 629 | coordinates representing a tangent vector per vertex, if targetSemantic is |
---|
| 630 | VES_TEXTURE_COORDINATES. If this already exists, it will be overwritten. |
---|
| 631 | @param splitMirrored |
---|
| 632 | Sets whether or not to split vertices when a mirrored tangent space |
---|
| 633 | transition is detected (matrix parity differs). @see TangentSpaceCalc::setSplitMirrored |
---|
| 634 | @param splitRotated |
---|
| 635 | Sets whether or not to split vertices when a rotated tangent space |
---|
| 636 | is detected. @see TangentSpaceCalc::setSplitRotated |
---|
| 637 | @param storeParityInW |
---|
| 638 | If @c true, store tangents as a 4-vector and include parity in w. |
---|
| 639 | */ |
---|
| 640 | void buildTangentVectors(VertexElementSemantic targetSemantic = VES_TANGENT, |
---|
| 641 | unsigned short sourceTexCoordSet = 0, unsigned short index = 0, |
---|
| 642 | bool splitMirrored = false, bool splitRotated = false, bool storeParityInW = false); |
---|
| 643 | |
---|
| 644 | /** Ask the mesh to suggest parameters to a future buildTangentVectors call, |
---|
| 645 | should you wish to use texture coordinates to store the tangents. |
---|
| 646 | @remarks |
---|
| 647 | This helper method will suggest source and destination texture coordinate sets |
---|
| 648 | for a call to buildTangentVectors. It will detect when there are inappropriate |
---|
| 649 | conditions (such as multiple geometry sets which don't agree). |
---|
| 650 | Moreover, it will return 'true' if it detects that there are aleady 3D |
---|
| 651 | coordinates in the mesh, and therefore tangents may have been prepared already. |
---|
| 652 | @param targetSemantic |
---|
| 653 | The semantic you intend to use to store the tangents |
---|
| 654 | if they are not already present; |
---|
| 655 | most likely options are VES_TEXTURE_COORDINATES or VES_TANGENT; you should |
---|
| 656 | use texture coordinates if you want compatibility with older, pre-SM2 |
---|
| 657 | graphics cards, and the tangent binding otherwise. |
---|
| 658 | @param outSourceCoordSet |
---|
| 659 | Reference to a source texture coordinate set which |
---|
| 660 | will be populated. |
---|
| 661 | @param outIndex |
---|
| 662 | Reference to a destination element index (e.g. texture coord set) |
---|
| 663 | which will be populated |
---|
| 664 | */ |
---|
| 665 | bool suggestTangentVectorBuildParams(VertexElementSemantic targetSemantic, |
---|
| 666 | unsigned short& outSourceCoordSet, unsigned short& outIndex); |
---|
| 667 | |
---|
| 668 | /** Builds an edge list for this mesh, which can be used for generating a shadow volume |
---|
| 669 | among other things. |
---|
| 670 | */ |
---|
| 671 | void buildEdgeList(void); |
---|
| 672 | /** Destroys and frees the edge lists this mesh has built. */ |
---|
| 673 | void freeEdgeList(void); |
---|
| 674 | |
---|
| 675 | /** This method prepares the mesh for generating a renderable shadow volume. |
---|
| 676 | @remarks |
---|
| 677 | Preparing a mesh to generate a shadow volume involves firstly ensuring that the |
---|
| 678 | vertex buffer containing the positions for the mesh is a standalone vertex buffer, |
---|
| 679 | with no other components in it. This method will therefore break apart any existing |
---|
| 680 | vertex buffers this mesh holds if position is sharing a vertex buffer. |
---|
| 681 | Secondly, it will double the size of this vertex buffer so that there are 2 copies of |
---|
| 682 | the position data for the mesh. The first half is used for the original, and the second |
---|
| 683 | half is used for the 'extruded' version of the mesh. The vertex count of the main |
---|
| 684 | VertexData used to render the mesh will remain the same though, so as not to add any |
---|
| 685 | overhead to regular rendering of the object. |
---|
| 686 | Both copies of the position are required in one buffer because shadow volumes stretch |
---|
| 687 | from the original mesh to the extruded version. |
---|
| 688 | @par |
---|
| 689 | Because shadow volumes are rendered in turn, no additional |
---|
| 690 | index buffer space is allocated by this method, a shared index buffer allocated by the |
---|
| 691 | shadow rendering algorithm is used for addressing this extended vertex buffer. |
---|
| 692 | */ |
---|
| 693 | void prepareForShadowVolume(void); |
---|
| 694 | |
---|
| 695 | /** Return the edge list for this mesh, building it if required. |
---|
| 696 | @remarks |
---|
| 697 | You must ensure that the Mesh as been prepared for shadow volume |
---|
| 698 | rendering if you intend to use this information for that purpose. |
---|
| 699 | @param lodIndex |
---|
| 700 | The LOD at which to get the edge list, 0 being the highest. |
---|
| 701 | */ |
---|
| 702 | EdgeData* getEdgeList(unsigned short lodIndex = 0); |
---|
| 703 | |
---|
| 704 | /** Return the edge list for this mesh, building it if required. |
---|
| 705 | @remarks |
---|
| 706 | You must ensure that the Mesh as been prepared for shadow volume |
---|
| 707 | rendering if you intend to use this information for that purpose. |
---|
| 708 | @param lodIndex |
---|
| 709 | The LOD at which to get the edge list, 0 being the highest. |
---|
| 710 | */ |
---|
| 711 | const EdgeData* getEdgeList(unsigned short lodIndex = 0) const; |
---|
| 712 | |
---|
| 713 | /** Returns whether this mesh has already had it's geometry prepared for use in |
---|
| 714 | rendering shadow volumes. */ |
---|
| 715 | bool isPreparedForShadowVolumes(void) const { return mPreparedForShadowVolumes; } |
---|
| 716 | |
---|
| 717 | /** Returns whether this mesh has an attached edge list. */ |
---|
| 718 | bool isEdgeListBuilt(void) const { return mEdgeListsBuilt; } |
---|
| 719 | |
---|
| 720 | /** Prepare matrices for software indexed vertex blend. |
---|
| 721 | @remarks |
---|
| 722 | This function organise bone indexed matrices to blend indexed matrices, |
---|
| 723 | so software vertex blending can access to the matrix via blend index |
---|
| 724 | directly. |
---|
| 725 | @param blendMatrices |
---|
| 726 | Pointer to an array of matrix pointers to store |
---|
| 727 | prepared results, which indexed by blend index. |
---|
| 728 | @param boneMatrices |
---|
| 729 | Pointer to an array of matrices to be used to blend, |
---|
| 730 | which indexed by bone index. |
---|
| 731 | @param indexMap |
---|
| 732 | The index map used to translate blend index to bone index. |
---|
| 733 | */ |
---|
| 734 | static void prepareMatricesForVertexBlend(const Matrix4** blendMatrices, |
---|
| 735 | const Matrix4* boneMatrices, const IndexMap& indexMap); |
---|
| 736 | |
---|
| 737 | /** Performs a software indexed vertex blend, of the kind used for |
---|
| 738 | skeletal animation although it can be used for other purposes. |
---|
| 739 | @remarks |
---|
| 740 | This function is supplied to update vertex data with blends |
---|
| 741 | done in software, either because no hardware support is available, |
---|
| 742 | or that you need the results of the blend for some other CPU operations. |
---|
| 743 | @param sourceVertexData |
---|
| 744 | VertexData class containing positions, normals, |
---|
| 745 | blend indices and blend weights. |
---|
| 746 | @param targetVertexData |
---|
| 747 | VertexData class containing target position |
---|
| 748 | and normal buffers which will be updated with the blended versions. |
---|
| 749 | Note that the layout of the source and target position / normal |
---|
| 750 | buffers must be identical, ie they must use the same buffer indexes |
---|
| 751 | @param blendMatrices |
---|
| 752 | Pointer to an array of matrix pointers to be used to blend, |
---|
| 753 | indexed by blend indices in the sourceVertexData |
---|
| 754 | @param numMatrices |
---|
| 755 | Number of matrices in the blendMatrices, it might be used |
---|
| 756 | as a hint for optimisation. |
---|
| 757 | @param blendNormals |
---|
| 758 | If @c true, normals are blended as well as positions. |
---|
| 759 | */ |
---|
| 760 | static void softwareVertexBlend(const VertexData* sourceVertexData, |
---|
| 761 | const VertexData* targetVertexData, |
---|
| 762 | const Matrix4* const* blendMatrices, size_t numMatrices, |
---|
| 763 | bool blendNormals); |
---|
| 764 | |
---|
| 765 | /** Performs a software vertex morph, of the kind used for |
---|
| 766 | morph animation although it can be used for other purposes. |
---|
| 767 | @remarks |
---|
| 768 | This function will linearly interpolate positions between two |
---|
| 769 | source buffers, into a third buffer. |
---|
| 770 | @param t |
---|
| 771 | Parametric distance between the start and end buffer positions. |
---|
| 772 | @param b1 |
---|
| 773 | Vertex buffer containing VET_FLOAT3 entries for the start positions. |
---|
| 774 | @param b2 |
---|
| 775 | Vertex buffer containing VET_FLOAT3 entries for the end positions. |
---|
| 776 | @param targetVertexData |
---|
| 777 | VertexData destination; assumed to have a separate position |
---|
| 778 | buffer already bound, and the number of vertices must agree with the |
---|
| 779 | number in start and end |
---|
| 780 | */ |
---|
| 781 | static void softwareVertexMorph(Real t, |
---|
| 782 | const HardwareVertexBufferSharedPtr& b1, |
---|
| 783 | const HardwareVertexBufferSharedPtr& b2, |
---|
| 784 | VertexData* targetVertexData); |
---|
| 785 | |
---|
| 786 | /** Performs a software vertex pose blend, of the kind used for |
---|
| 787 | morph animation although it can be used for other purposes. |
---|
| 788 | @remarks |
---|
| 789 | This function will apply a weighted offset to the positions in the |
---|
| 790 | incoming vertex data (therefore this is a read/write operation, and |
---|
| 791 | if you expect to call it more than once with the same data, then |
---|
| 792 | you would be best to suppress hardware uploads of the position buffer |
---|
| 793 | for the duration). |
---|
| 794 | @param weight |
---|
| 795 | Parametric weight to scale the offsets by. |
---|
| 796 | @param vertexOffsetMap |
---|
| 797 | Potentially sparse map of vertex index -> offset. |
---|
| 798 | @param normalsMap |
---|
| 799 | Potentially sparse map of vertex index -> normal. |
---|
| 800 | @param targetVertexData |
---|
| 801 | VertexData destination; assumed to have a separate position |
---|
| 802 | buffer already bound, and the number of vertices must agree with the |
---|
| 803 | number in start and end. |
---|
| 804 | */ |
---|
| 805 | static void softwareVertexPoseBlend(Real weight, |
---|
| 806 | const map<size_t, Vector3>::type& vertexOffsetMap, |
---|
| 807 | const map<size_t, Vector3>::type& normalsMap, |
---|
| 808 | VertexData* targetVertexData); |
---|
| 809 | /** Gets a reference to the optional name assignments of the SubMeshes. */ |
---|
| 810 | const SubMeshNameMap& getSubMeshNameMap(void) const { return mSubMeshNameMap; } |
---|
| 811 | |
---|
| 812 | /** Sets whether or not this Mesh should automatically build edge lists |
---|
| 813 | when asked for them, or whether it should never build them if |
---|
| 814 | they are not already provided. |
---|
| 815 | @remarks |
---|
| 816 | This allows you to create meshes which do not have edge lists calculated, |
---|
| 817 | because you never want to use them. This value defaults to 'true' |
---|
| 818 | for mesh formats which did not include edge data, and 'false' for |
---|
| 819 | newer formats, where edge lists are expected to have been generated |
---|
| 820 | in advance. |
---|
| 821 | */ |
---|
| 822 | void setAutoBuildEdgeLists(bool autobuild) { mAutoBuildEdgeLists = autobuild; } |
---|
| 823 | /** Sets whether or not this Mesh should automatically build edge lists |
---|
| 824 | when asked for them, or whether it should never build them if |
---|
| 825 | they are not already provided. |
---|
| 826 | */ |
---|
| 827 | bool getAutoBuildEdgeLists(void) const { return mAutoBuildEdgeLists; } |
---|
| 828 | |
---|
| 829 | /** Gets the type of vertex animation the shared vertex data of this mesh supports. |
---|
| 830 | */ |
---|
| 831 | virtual VertexAnimationType getSharedVertexDataAnimationType(void) const; |
---|
| 832 | |
---|
| 833 | /// Returns whether animation on shared vertex data includes normals. |
---|
| 834 | bool getSharedVertexDataAnimationIncludesNormals() const { return mSharedVertexDataAnimationIncludesNormals; } |
---|
| 835 | |
---|
| 836 | /** Creates a new Animation object for vertex animating this mesh. |
---|
| 837 | @param name |
---|
| 838 | The name of this animation. |
---|
| 839 | @param length |
---|
| 840 | The length of the animation in seconds. |
---|
| 841 | */ |
---|
| 842 | virtual Animation* createAnimation(const String& name, Real length); |
---|
| 843 | |
---|
| 844 | /** Returns the named vertex Animation object. |
---|
| 845 | @param name |
---|
| 846 | The name of the animation. |
---|
| 847 | */ |
---|
| 848 | virtual Animation* getAnimation(const String& name) const; |
---|
| 849 | |
---|
| 850 | /** Internal access to the named vertex Animation object - returns null |
---|
| 851 | if it does not exist. |
---|
| 852 | @param name |
---|
| 853 | The name of the animation. |
---|
| 854 | */ |
---|
| 855 | virtual Animation* _getAnimationImpl(const String& name) const; |
---|
| 856 | |
---|
| 857 | /** Returns whether this mesh contains the named vertex animation. */ |
---|
| 858 | virtual bool hasAnimation(const String& name) const; |
---|
| 859 | |
---|
| 860 | /** Removes vertex Animation from this mesh. */ |
---|
| 861 | virtual void removeAnimation(const String& name); |
---|
| 862 | |
---|
| 863 | /** Gets the number of morph animations in this mesh. */ |
---|
| 864 | virtual unsigned short getNumAnimations(void) const; |
---|
| 865 | |
---|
| 866 | /** Gets a single morph animation by index. |
---|
| 867 | */ |
---|
| 868 | virtual Animation* getAnimation(unsigned short index) const; |
---|
| 869 | |
---|
| 870 | /** Removes all morph Animations from this mesh. */ |
---|
| 871 | virtual void removeAllAnimations(void); |
---|
| 872 | /** Gets a pointer to a vertex data element based on a morph animation |
---|
| 873 | track handle. |
---|
| 874 | @remarks |
---|
| 875 | 0 means the shared vertex data, 1+ means a submesh vertex data (index+1) |
---|
| 876 | */ |
---|
| 877 | VertexData* getVertexDataByTrackHandle(unsigned short handle); |
---|
| 878 | /** Iterates through all submeshes and requests them |
---|
| 879 | to apply their texture aliases to the material they use. |
---|
| 880 | @remarks |
---|
| 881 | The submesh will only apply texture aliases to the material if matching |
---|
| 882 | texture alias names are found in the material. If a match is found, the |
---|
| 883 | submesh will automatically clone the original material and then apply its |
---|
| 884 | texture to the new material. |
---|
| 885 | @par |
---|
| 886 | This method is normally called by the protected method loadImpl when a |
---|
| 887 | mesh if first loaded. |
---|
| 888 | */ |
---|
| 889 | void updateMaterialForAllSubMeshes(void); |
---|
| 890 | |
---|
| 891 | /** Internal method which, if animation types have not been determined, |
---|
| 892 | scans any vertex animations and determines the type for each set of |
---|
| 893 | vertex data (cannot have 2 different types). |
---|
| 894 | */ |
---|
| 895 | void _determineAnimationTypes(void) const; |
---|
| 896 | /** Are the derived animation types out of date? */ |
---|
| 897 | bool _getAnimationTypesDirty(void) const { return mAnimationTypesDirty; } |
---|
| 898 | |
---|
| 899 | /** Create a new Pose for this mesh or one of its submeshes. |
---|
| 900 | @param target |
---|
| 901 | The target geometry index; 0 is the shared Mesh geometry, 1+ is the |
---|
| 902 | dedicated SubMesh geometry belonging to submesh index + 1. |
---|
| 903 | @param name |
---|
| 904 | Name to give the pose, which is optional. |
---|
| 905 | @return |
---|
| 906 | A new Pose ready for population. |
---|
| 907 | */ |
---|
| 908 | Pose* createPose(ushort target, const String& name = StringUtil::BLANK); |
---|
| 909 | /** Get the number of poses.*/ |
---|
| 910 | size_t getPoseCount(void) const { return mPoseList.size(); } |
---|
| 911 | /** Retrieve an existing Pose by index.*/ |
---|
| 912 | Pose* getPose(ushort index); |
---|
| 913 | /** Retrieve an existing Pose by name.*/ |
---|
| 914 | Pose* getPose(const String& name); |
---|
| 915 | /** Destroy a pose by index. |
---|
| 916 | @note |
---|
| 917 | This will invalidate any animation tracks referring to this pose or those after it. |
---|
| 918 | */ |
---|
| 919 | void removePose(ushort index); |
---|
| 920 | /** Destroy a pose by name. |
---|
| 921 | @note |
---|
| 922 | This will invalidate any animation tracks referring to this pose or those after it. |
---|
| 923 | */ |
---|
| 924 | void removePose(const String& name); |
---|
| 925 | /** Destroy all poses. */ |
---|
| 926 | void removeAllPoses(void); |
---|
| 927 | |
---|
| 928 | typedef VectorIterator<PoseList> PoseIterator; |
---|
| 929 | typedef ConstVectorIterator<PoseList> ConstPoseIterator; |
---|
| 930 | |
---|
| 931 | /** Get an iterator over all the poses defined. */ |
---|
| 932 | PoseIterator getPoseIterator(void); |
---|
| 933 | /** Get an iterator over all the poses defined. */ |
---|
| 934 | ConstPoseIterator getPoseIterator(void) const; |
---|
| 935 | /** Get pose list. */ |
---|
| 936 | const PoseList& getPoseList(void) const; |
---|
| 937 | |
---|
| 938 | /** Get LOD strategy used by this mesh. */ |
---|
| 939 | const LodStrategy *getLodStrategy() const; |
---|
| 940 | /** Set the LOD strategy used by this mesh. */ |
---|
| 941 | void setLodStrategy(LodStrategy *lodStrategy); |
---|
| 942 | |
---|
| 943 | }; |
---|
| 944 | |
---|
| 945 | /** A way of recording the way each LODs is recorded this Mesh. */ |
---|
| 946 | struct MeshLodUsage |
---|
| 947 | { |
---|
| 948 | /** User-supplied values used to determine when th is LOD applies. |
---|
| 949 | @remarks |
---|
| 950 | This is required in case the LOD strategy changes. |
---|
| 951 | */ |
---|
| 952 | Real userValue; |
---|
| 953 | |
---|
| 954 | /** Value used by to determine when this LOD applies. |
---|
| 955 | @remarks |
---|
| 956 | May be interpretted differently by different strategies. |
---|
| 957 | Transformed from user-supplied values with LodStrategy::transformUserValue. |
---|
| 958 | */ |
---|
| 959 | Real value; |
---|
| 960 | |
---|
| 961 | /// Only relevant if mIsLodManual is true, the name of the alternative mesh to use. |
---|
| 962 | String manualName; |
---|
| 963 | /// Only relevant if mIsLodManual is true, the name of the group of the alternative mesh. |
---|
| 964 | String manualGroup; |
---|
| 965 | /// Hard link to mesh to avoid looking up each time. |
---|
| 966 | mutable MeshPtr manualMesh; |
---|
| 967 | /// Edge list for this LOD level (may be derived from manual mesh). |
---|
| 968 | mutable EdgeData* edgeData; |
---|
| 969 | |
---|
| 970 | MeshLodUsage() : userValue(0.0), value(0.0), edgeData(0) {} |
---|
| 971 | }; |
---|
| 972 | |
---|
| 973 | /** @} */ |
---|
| 974 | /** @} */ |
---|
| 975 | |
---|
| 976 | |
---|
| 977 | } // namespace Ogre |
---|
| 978 | |
---|
| 979 | #include "OgreHeaderSuffix.h" |
---|
| 980 | |
---|
| 981 | #endif // __Mesh_H__ |
---|