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