Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogre_src_v1-9-0/OgreMain/include/OgreInstancedEntity.h @ 148

Last change on this file since 148 was 148, checked in by patricwi, 6 years ago

Added new dependencies for ogre1.9 and cegui0.8

File size: 12.4 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2013 Torus Knot Software Ltd
8
9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal
11in the Software without restriction, including without limitation the rights
12to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13copies of the Software, and to permit persons to whom the Software is
14furnished to do so, subject to the following conditions:
15
16The above copyright notice and this permission notice shall be included in
17all copies or substantial portions of the Software.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25THE SOFTWARE.
26-----------------------------------------------------------------------------
27*/
28#ifndef __InstancedEntity_H__
29#define __InstancedEntity_H__
30
31#include "OgreMovableObject.h"
32#include "OgreNode.h"
33#include "OgreHeaderPrefix.h"
34
35namespace Ogre
36{
37        /** \addtogroup Core
38        *  @{
39        */
40        /** \addtogroup Scene
41        *  @{
42        */
43
44        /** @see InstanceBatch to understand how instancing works.
45
46                Instanced entities work in a very similar way as how an Entity works, as this interface
47                tries to mimic it as most as possible to make the transition between Entity and InstancedEntity
48                as straightforward and simple as possible.
49                There are a couple inherent limitations, for example setRenderQueueGroup only works on
50                the InstanceBatch level, not the individual instance. This limits Z sorting for alpha blending
51                quite significantly
52                An InstancedEntity won't appear in scene until a SceneNode is attached to them. Once the
53                InstancedEntity is no longer needed, call InstanceBatch::removeInstancedEntity to put them
54                back into a queue so the batch can return it back again when a new instance is requested.
55                @par
56                Internally, instanced entities that are not visible (i.e. by setting setVisible(false) or
57                when they don't have a SceneNode attached to them) a Zero world matrix is sent to the vertex shader
58                which in turn causes a zero area triangle.
59                This obviously means no Vertex shader benefit, but saves a bit of pixel shader processing power.
60                Also this means this object won't be considered when sizing the InstanceBatch's bounding box.
61                @par
62                Each instance has an instance ID unique within the batch, which matches the ID sent to the vertex
63                shader by some techniques (like InstanceBatchShader).
64                @par
65                Differences between Entity and InstancedEntity:
66                * Setting RenderQueueGroup and other Renderable stuff works at InstanceBatch level, not
67                InstancedEntity. This is obviously a limitation from instancing in general, not this particular
68                implementation
69
70        @remarks
71                        Design discussion webpage
72        @author
73            Matias N. Goldberg ("dark_sylinc")
74        @version
75            1.0
76     */
77        class _OgreExport InstancedEntity : public Ogre::MovableObject
78        {
79                friend class InstanceBatch;
80                friend class InstanceBatchShader;
81                friend class InstanceBatchHW;
82                friend class InstanceBatchHW_VTF;
83                friend class BaseInstanceBatchVTF;
84        protected:
85                uint16 mInstanceId; //Note it may change after defragmenting!
86                bool mInUse;
87                InstanceBatch *mBatchOwner;
88
89                AnimationStateSet *mAnimationState;
90                SkeletonInstance *mSkeletonInstance;
91                Matrix4 *mBoneMatrices;  //Local space
92                Matrix4 *mBoneWorldMatrices; //World space
93                unsigned long mFrameAnimationLastUpdated;
94
95                InstancedEntity* mSharedTransformEntity;        //When not null, another InstancedEntity controls the skeleton
96                                                                                               
97                /** Used in conjunction with bone matrix lookup. Tells the number of the transform for
98            as arranged in the vertex texture */
99                uint16 mTransformLookupNumber;
100
101                /// Stores the master when we're the slave, store our slaves when we're the master
102                typedef vector<InstancedEntity*>::type InstancedEntityVec;
103                InstancedEntityVec mSharingPartners;
104
105                //////////////////////////////////////////////////////////////////////////
106                // Parameters used for local transformation offset information
107                // The
108                //////////////////////////////////////////////////////////////////////////
109
110                /// Object position
111                Vector3 mPosition;
112                Vector3 mDerivedLocalPosition;
113                /// Object orientation
114                Quaternion mOrientation;
115                /// Object scale
116                Vector3 mScale;
117                /// The maximum absolute scale for all dimension
118                Real mMaxScaleLocal;
119                /// Full world transform
120                Matrix4 mFullLocalTransform;
121                /// Tells if mFullTransform needs an updated
122                bool mNeedTransformUpdate;
123                /// Tells if the animation world transform needs an update
124                bool mNeedAnimTransformUpdate;
125                /// Tells whether to use the local transform parameters
126                bool mUseLocalTransform;
127
128
129                /// Returns number of matrices written to transform, assumes transform has enough space
130                size_t getTransforms( Matrix4 *xform ) const;
131                /// Returns number of 32-bit values written
132                size_t getTransforms3x4( float *xform ) const;
133
134                /// Returns true if this InstancedObject is visible to the current camera
135                bool findVisible( Camera *camera ) const;
136
137                /// Creates/destroys our own skeleton, also tells slaves to unlink if we're destroying
138                void createSkeletonInstance();
139                void destroySkeletonInstance();
140
141                /// When this entity is a slave, stopSharingTransform delegates to this function.
142                ///     nofityMaster = false is used to prevent iterator invalidation in specific cases.
143                void stopSharingTransformAsSlave( bool notifyMaster );
144
145                /// Just unlinks, and tells our master we're no longer sharing
146                void unlinkTransform( bool notifyMaster=true );
147
148                /// Called when a slave has unlinked from us
149                void notifyUnlink( const InstancedEntity *slave );
150
151                /// Mark the transformation matrixes as dirty
152                inline void markTransformDirty();
153
154                /// Incremented count for next name extension
155        static NameGenerator msNameGenerator;
156
157        public:
158                InstancedEntity( InstanceBatch *batchOwner, uint32 instanceID, InstancedEntity* sharedTransformEntity = NULL);
159                virtual ~InstancedEntity();
160
161                /** Shares the entire transformation with another InstancedEntity. This is useful when a mesh
162                        has more than one submeshes, therefore creating multiple InstanceManagers (one for each
163                        submesh). With this function, sharing makes the skeleton to be shared (less memory) and
164                        updated once (performance optimization).
165                        Note that one InstancedEntity (i.e. submesh 0) must be chosen as "master" which will share
166                        with the other instanced entities (i.e. submeshes 1-N) which are called "slaves"
167                        @par
168                        Requirements to share trasnformations:
169                                * Both InstancedEntities must have use the same skeleton
170                                * An InstancedEntity can't be both "master" and "slave" at the same time
171                        @remarks
172                        Sharing does nothing if the original mesh doesn't have a skeleton
173                        When an InstancedEntity is removed (@see InstanceBatch::removeInstancedEntity), it stops
174                        sharing the transform. If the instanced entity was the master one, all it's slaves stop
175                        sharing and start having their own transform too.
176                        @param slave The InstancedEntity that should share with us and become our slave
177                        @return true if successfully shared (may fail if they aren't skeletally animated)
178                */
179                bool shareTransformWith( InstancedEntity *slave );
180
181                /** @see shareTransformWith
182                        Stops sharing the transform if this is a slave, and notifies the master we're no longer
183                        a slave.
184                        If this is a master, tells all it's slave to stop sharing
185                        @remarks
186                        This function is automatically called in InstanceBatch::removeInstancedEntity
187                */
188                void stopSharingTransform();
189
190                InstanceBatch* _getOwner() const { return mBatchOwner; }
191
192                const String& getMovableType(void) const;
193
194                const AxisAlignedBox& getBoundingBox(void) const;
195                Real getBoundingRadius(void) const;
196
197                /** This is used by our batch owner to get the closest entity's depth, returns infinity
198            when not attached to a scene node */
199                Real getSquaredViewDepth( const Camera* cam ) const;
200
201                /// Overridden so we can tell the InstanceBatch it needs to update it's bounds
202                void _notifyMoved(void);
203                void _notifyAttached( Node* parent, bool isTagPoint = false );
204
205                /// Do nothing, InstanceBatch takes care of this.
206                void _updateRenderQueue( RenderQueue* queue )   {}
207                void visitRenderables( Renderable::Visitor* visitor, bool debugRenderables = false ) {}
208
209                /** @see Entity::hasSkeleton */
210                bool hasSkeleton(void) const { return mSkeletonInstance != 0; }
211                /** @see Entity::getSkeleton */
212                SkeletonInstance* getSkeleton(void) const { return mSkeletonInstance; }
213
214                /** @see Entity::getAnimationState */
215                AnimationState* getAnimationState(const String& name) const;
216                /** @see Entity::getAllAnimationStates */
217                AnimationStateSet* getAllAnimationStates(void) const;
218
219                /** Called by InstanceBatch in <i>his</i> _updateRenderQueue to tell us we need
220                        to calculate our bone matrices.
221                        @remarks Assumes it has a skeleton (mSkeletonInstance != 0)
222                        @return true if something was actually updated
223                */
224                virtual bool _updateAnimation(void);
225
226                /** Sets the transformation look up number */
227                void setTransformLookupNumber(uint16 num) { mTransformLookupNumber = num;}
228
229                /** Retrieve the position */
230                const Vector3& getPosition() const { return mPosition; }
231                /** Set the position or the offset from the parent node if a parent node exists */ 
232                void setPosition(const Vector3& position, bool doUpdate = true);
233
234                /** Retrieve the orientation */
235                const Quaternion& getOrientation() const { return mOrientation; }
236                /** Set the orientation or the offset from the parent node if a parent node exists */
237                void setOrientation(const Quaternion& orientation, bool doUpdate = true);
238
239                /** Retrieve the local scale */ 
240                const Vector3& getScale() const { return mScale; }
241                /** Set the  scale or the offset from the parent node if a parent node exists  */ 
242                void setScale(const Vector3& scale, bool doUpdate = true);
243
244                /** Returns the maximum derived scale coefficient among the xyz values */
245                Real getMaxScaleCoef() const;
246
247                /** Update the world transform and derived values */
248                void updateTransforms();
249
250                /** Tells if the entity is in use. */
251                bool isInUse() const { return mInUse; }
252                /** Sets whether the entity is in use. */
253                void setInUse(bool used);
254
255                /** Returns the world transform of the instanced entity including local transform */
256                virtual const Matrix4& _getParentNodeFullTransform(void) const { 
257                        assert((!mNeedTransformUpdate || !mUseLocalTransform) && "Transform data should be updated at this point");
258                        return mUseLocalTransform ? mFullLocalTransform :
259                                mParentNode ? mParentNode->_getFullTransform() : Matrix4::IDENTITY;
260                }
261
262                /** Returns the derived position of the instanced entity including local transform */
263                const Vector3& _getDerivedPosition() const {
264                        assert((!mNeedTransformUpdate || !mUseLocalTransform) && "Transform data should be updated at this point");
265                        return mUseLocalTransform ? mDerivedLocalPosition :
266                                mParentNode ? mParentNode->_getDerivedPosition() : Vector3::ZERO;
267                }
268
269                /** @copydoc MovableObject::isInScene. */
270                virtual bool isInScene(void) const
271                {
272                        //We assume that the instanced entity is in the scene if it is in use
273                        //It is in the scene whether it has a parent node or not
274                        return mInUse;
275                }
276
277                /** Sets the custom parameter for this instance @see InstanceManager::setNumCustomParams
278                        Because not all techniques support custom params, and some users may not need it while
279                        using millions of InstancedEntities, the params have been detached from InstancedEntity
280                        and stored in it's InstanceBatch instead, to reduce memory overhead.
281                @remarks
282                        If this function is never called, all instances default to Vector4::ZERO. Watch out!
283                        If you destroy an instanced entity and then create it again (remember! Instanced entities
284                        are pre-allocated) it's custom param will contain the old value when it was destroyed.
285                @param idx of the param. In the range [0; InstanceManager::getNumCustomParams())
286                @param newParam New parameter
287                */
288                void setCustomParam( unsigned char idx, const Vector4 &newParam );
289                const Vector4& getCustomParam( unsigned char idx );
290        };
291}
292
293#include "OgreHeaderSuffix.h"
294
295#endif
Note: See TracBrowser for help on using the repository browser.