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