Coverage Report

Created: 2025-08-25 06:48

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