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