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