Patch 2793067: fix trunk with OGRE_THREAD_SUPPORT=1 on non-Windows platforms (don...
[ogre3d.git] / OgreMain / src / OgreEntity.cpp
blob9577c9c76364fee2251a4c70b25781763df994a2
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
7 Copyright (c) 2000-2006 Torus Knot Software Ltd
8 Also see acknowledgements in Readme.html
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.
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.
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.
24 You may alternatively use this source under the terms of a specific version of
25 the OGRE Unrestricted License provided you have obtained such a license from
26 Torus Knot Software Ltd.
27 -----------------------------------------------------------------------------
29 #include "OgreStableHeaders.h"
30 #include "OgreEntity.h"
32 #include "OgreMeshManager.h"
33 #include "OgreSubMesh.h"
34 #include "OgreSubEntity.h"
35 #include "OgreException.h"
36 #include "OgreSceneManager.h"
37 #include "OgreLogManager.h"
38 #include "OgreSkeleton.h"
39 #include "OgreBone.h"
40 #include "OgreCamera.h"
41 #include "OgreTagPoint.h"
42 #include "OgreAxisAlignedBox.h"
43 #include "OgreHardwareBufferManager.h"
44 #include "OgreVector4.h"
45 #include "OgreRoot.h"
46 #include "OgreTechnique.h"
47 #include "OgrePass.h"
48 #include "OgreSkeletonInstance.h"
49 #include "OgreEdgeListBuilder.h"
50 #include "OgreStringConverter.h"
51 #include "OgreAnimation.h"
52 #include "OgreOptimisedUtil.h"
53 #include "OgreSceneNode.h"
54 #include "OgreLodStrategy.h"
55 #include "OgreLodListener.h"
57 namespace Ogre {
58 //-----------------------------------------------------------------------
59 Entity::Entity ()
60 : mAnimationState(NULL),
61 mSkelAnimVertexData(0),
62 mSoftwareVertexAnimVertexData(0),
63 mHardwareVertexAnimVertexData(0),
64 mPreparedForShadowVolumes(false),
65 mBoneWorldMatrices(NULL),
66 mBoneMatrices(NULL),
67 mNumBoneMatrices(0),
68 mFrameAnimationLastUpdated(std::numeric_limits<unsigned long>::max()),
69 mFrameBonesLastUpdated(NULL),
70 mSharedSkeletonEntities(NULL),
71 mDisplaySkeleton(false),
72 mHardwareAnimation(false),
73 mHardwarePoseCount(0),
74 mVertexProgramInUse(false),
75 mSoftwareAnimationRequests(0),
76 mSoftwareAnimationNormalsRequests(0),
77 mMeshLodIndex(0),
78 mMeshLodFactorTransformed(1.0f),
79 mMinMeshLodIndex(99),
80 mMaxMeshLodIndex(0), // Backwards, remember low value = high detail
81 mMaterialLodFactor(1.0f),
82 mMaterialLodFactorTransformed(1.0f),
83 mMinMaterialLodIndex(99),
84 mMaxMaterialLodIndex(0), // Backwards, remember low value = high detail
85 mSkeletonInstance(0),
86 mInitialised(false),
87 mLastParentXform(Matrix4::ZERO),
88 mMeshStateCount(0),
89 mFullBoundingBox()
92 //-----------------------------------------------------------------------
93 Entity::Entity( const String& name, const MeshPtr& mesh) :
94 MovableObject(name),
95 mMesh(mesh),
96 mAnimationState(NULL),
97 mSkelAnimVertexData(0),
98 mSoftwareVertexAnimVertexData(0),
99 mHardwareVertexAnimVertexData(0),
100 mPreparedForShadowVolumes(false),
101 mBoneWorldMatrices(NULL),
102 mBoneMatrices(NULL),
103 mNumBoneMatrices(0),
104 mFrameAnimationLastUpdated(std::numeric_limits<unsigned long>::max()),
105 mFrameBonesLastUpdated(NULL),
106 mSharedSkeletonEntities(NULL),
107 mDisplaySkeleton(false),
108 mHardwareAnimation(false),
109 mVertexProgramInUse(false),
110 mSoftwareAnimationRequests(0),
111 mSoftwareAnimationNormalsRequests(0),
112 mMeshLodIndex(0),
113 mMeshLodFactorTransformed(1.0f),
114 mMinMeshLodIndex(99),
115 mMaxMeshLodIndex(0), // Backwards, remember low value = high detail
116 mMaterialLodFactor(1.0f),
117 mMaterialLodFactorTransformed(1.0f),
118 mMinMaterialLodIndex(99),
119 mMaxMaterialLodIndex(0), // Backwards, remember low value = high detail
120 mSkeletonInstance(0),
121 mInitialised(false),
122 mLastParentXform(Matrix4::ZERO),
123 mMeshStateCount(0),
124 mFullBoundingBox()
126 _initialise();
128 //-----------------------------------------------------------------------
129 void Entity::backgroundLoadingComplete(Resource* res)
131 if (res == mMesh.get())
133 // mesh loading has finished, we can construct ourselves now
134 _initialise();
137 //-----------------------------------------------------------------------
138 void Entity::_initialise(bool forceReinitialise)
140 if (forceReinitialise)
141 _deinitialise();
143 if (mInitialised)
144 return;
146 if (mMesh->isBackgroundLoaded() && !mMesh->isLoaded())
148 // register for a callback when mesh is finished loading
149 // do this before asking for load to happen to avoid race
150 mMesh->addListener(this);
153 // On-demand load
154 mMesh->load();
155 // If loading failed, or deferred loading isn't done yet, defer
156 // Will get a callback in the case of deferred loading
157 // Skeletons are cascade-loaded so no issues there
158 if (!mMesh->isLoaded())
159 return;
161 // Is mesh skeletally animated?
162 if (mMesh->hasSkeleton() && !mMesh->getSkeleton().isNull())
164 mSkeletonInstance = OGRE_NEW SkeletonInstance(mMesh->getSkeleton());
165 mSkeletonInstance->load();
168 // Build main subentity list
169 buildSubEntityList(mMesh, &mSubEntityList);
171 // Check if mesh is using manual LOD
172 if (mMesh->isLodManual())
174 ushort i, numLod;
175 numLod = mMesh->getNumLodLevels();
176 // NB skip LOD 0 which is the original
177 for (i = 1; i < numLod; ++i)
179 const MeshLodUsage& usage = mMesh->getLodLevel(i);
180 // Manually create entity
181 Entity* lodEnt = OGRE_NEW Entity(mName + "Lod" + StringConverter::toString(i),
182 usage.manualMesh);
183 mLodEntityList.push_back(lodEnt);
188 // Initialise the AnimationState, if Mesh has animation
189 if (hasSkeleton())
191 mFrameBonesLastUpdated = OGRE_NEW_T(unsigned long, MEMCATEGORY_ANIMATION)(std::numeric_limits<unsigned long>::max());
192 mNumBoneMatrices = mSkeletonInstance->getNumBones();
193 mBoneMatrices = static_cast<Matrix4*>(OGRE_MALLOC_SIMD(sizeof(Matrix4) * mNumBoneMatrices, MEMCATEGORY_ANIMATION));
195 if (hasSkeleton() || hasVertexAnimation())
197 mAnimationState = OGRE_NEW AnimationStateSet();
198 mMesh->_initAnimationState(mAnimationState);
199 prepareTempBlendBuffers();
202 reevaluateVertexProcessing();
204 // Update of bounds of the parent SceneNode, if Entity already attached
205 // this can happen if Mesh is loaded in background or after reinitialisation
206 if( mParentNode )
208 getParentSceneNode()->needUpdate();
211 mInitialised = true;
212 mMeshStateCount = mMesh->getStateCount();
215 //-----------------------------------------------------------------------
216 void Entity::_deinitialise(void)
218 if (!mInitialised)
219 return;
221 // Delete submeshes
222 SubEntityList::iterator i, iend;
223 iend = mSubEntityList.end();
224 for (i = mSubEntityList.begin(); i != iend; ++i)
226 // Delete SubEntity
227 OGRE_DELETE *i;
229 mSubEntityList.clear();
231 // Delete LOD entities
232 LODEntityList::iterator li, liend;
233 liend = mLodEntityList.end();
234 for (li = mLodEntityList.begin(); li != liend; ++li)
236 // Delete
237 OGRE_DELETE (*li);
239 mLodEntityList.clear();
241 // Delete shadow renderables
242 ShadowRenderableList::iterator si, siend;
243 siend = mShadowRenderables.end();
244 for (si = mShadowRenderables.begin(); si != siend; ++si)
246 OGRE_DELETE *si;
248 mShadowRenderables.clear();
250 // Detach all child objects, do this manually to avoid needUpdate() call
251 // which can fail because of deleted items
252 detachAllObjectsImpl();
254 if (mSkeletonInstance) {
255 OGRE_FREE_SIMD(mBoneWorldMatrices, MEMCATEGORY_ANIMATION);
257 if (mSharedSkeletonEntities) {
258 mSharedSkeletonEntities->erase(this);
259 if (mSharedSkeletonEntities->size() == 1)
261 (*mSharedSkeletonEntities->begin())->stopSharingSkeletonInstance();
263 // Should never occuring, just in case
264 else if (mSharedSkeletonEntities->empty())
266 OGRE_DELETE_T(mSharedSkeletonEntities, EntitySet, MEMCATEGORY_ANIMATION);
267 // using OGRE_FREE since unsigned long is not a destructor
268 OGRE_FREE(mFrameBonesLastUpdated, MEMCATEGORY_ANIMATION);
269 OGRE_DELETE mSkeletonInstance;
270 OGRE_FREE_SIMD(mBoneMatrices, MEMCATEGORY_ANIMATION);
271 OGRE_DELETE mAnimationState;
273 } else {
274 // using OGRE_FREE since unsigned long is not a destructor
275 OGRE_FREE(mFrameBonesLastUpdated, MEMCATEGORY_ANIMATION);
276 OGRE_DELETE mSkeletonInstance;
277 OGRE_FREE_SIMD(mBoneMatrices, MEMCATEGORY_ANIMATION);
278 OGRE_DELETE mAnimationState;
281 else if (hasVertexAnimation())
283 OGRE_DELETE mAnimationState;
286 OGRE_DELETE mSkelAnimVertexData;
287 OGRE_DELETE mSoftwareVertexAnimVertexData;
288 OGRE_DELETE mHardwareVertexAnimVertexData;
290 mInitialised = false;
292 //-----------------------------------------------------------------------
293 Entity::~Entity()
295 _deinitialise();
296 // Unregister our listener
297 mMesh->removeListener(this);
299 //-----------------------------------------------------------------------
300 bool Entity::hasVertexAnimation(void) const
302 return mMesh->hasVertexAnimation();
304 //-----------------------------------------------------------------------
305 const MeshPtr& Entity::getMesh(void) const
307 return mMesh;
309 //-----------------------------------------------------------------------
310 SubEntity* Entity::getSubEntity(unsigned int index) const
312 if (index >= mSubEntityList.size())
313 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
314 "Index out of bounds.",
315 "Entity::getSubEntity");
316 return mSubEntityList[index];
318 //-----------------------------------------------------------------------
319 SubEntity* Entity::getSubEntity(const String& name) const
321 ushort index = mMesh->_getSubMeshIndex(name);
322 return getSubEntity(index);
324 //-----------------------------------------------------------------------
325 unsigned int Entity::getNumSubEntities(void) const
327 return static_cast< unsigned int >( mSubEntityList.size() );
329 //-----------------------------------------------------------------------
330 Entity* Entity::clone( const String& newName) const
332 if (!mManager)
334 OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
335 "Cannot clone an Entity that wasn't created through a "
336 "SceneManager", "Entity::clone");
338 Entity* newEnt = mManager->createEntity(newName, getMesh()->getName() );
340 if (mInitialised)
342 // Copy material settings
343 SubEntityList::const_iterator i;
344 unsigned int n = 0;
345 for (i = mSubEntityList.begin(); i != mSubEntityList.end(); ++i, ++n)
347 newEnt->getSubEntity(n)->setMaterialName((*i)->getMaterialName());
349 if (mAnimationState)
351 OGRE_DELETE newEnt->mAnimationState;
352 newEnt->mAnimationState = OGRE_NEW AnimationStateSet(*mAnimationState);
356 return newEnt;
358 //-----------------------------------------------------------------------
359 void Entity::setMaterialName( const String& name, const String& groupName /* = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME */)
361 // Set for all subentities
362 SubEntityList::iterator i;
363 for (i = mSubEntityList.begin(); i != mSubEntityList.end(); ++i)
365 (*i)->setMaterialName(name);
371 void Entity::setMaterial( const MaterialPtr& material )
373 // Set for all subentities
374 SubEntityList::iterator i;
375 for (i = mSubEntityList.begin(); i != mSubEntityList.end(); ++i)
377 (*i)->setMaterial(material);
381 //-----------------------------------------------------------------------
382 void Entity::_notifyCurrentCamera(Camera* cam)
384 MovableObject::_notifyCurrentCamera(cam);
386 // Calculate the LOD
387 if (mParentNode)
389 // Get mesh lod strategy
390 const LodStrategy *meshStrategy = mMesh->getLodStrategy();
391 // Get the appropriate lod value
392 Real lodValue = meshStrategy->getValue(this, cam);
393 // Bias the lod value
394 Real biasedMeshLodValue = lodValue * mMeshLodFactorTransformed;
397 // Get the index at this biased depth
398 ushort newMeshLodIndex = mMesh->getLodIndex(biasedMeshLodValue);
399 // Apply maximum detail restriction (remember lower = higher detail)
400 newMeshLodIndex = std::max(mMaxMeshLodIndex, newMeshLodIndex);
401 // Apply minimum detail restriction (remember higher = lower detail)
402 newMeshLodIndex = std::min(mMinMeshLodIndex, newMeshLodIndex);
404 // Construct event object
405 EntityMeshLodChangedEvent evt;
406 evt.entity = this;
407 evt.camera = cam;
408 evt.lodValue = biasedMeshLodValue;
409 evt.previousLodIndex = mMeshLodIndex;
410 evt.newLodIndex = newMeshLodIndex;
412 // Notify lod event listeners
413 cam->getSceneManager()->_notifyEntityMeshLodChanged(evt);
415 // Change lod index
416 mMeshLodIndex = evt.newLodIndex;
418 // Now do material LOD
419 lodValue *= mMaterialLodFactorTransformed;
423 SubEntityList::iterator i, iend;
424 iend = mSubEntityList.end();
425 for (i = mSubEntityList.begin(); i != iend; ++i)
427 // Get sub-entity material
428 MaterialPtr material = (*i)->mpMaterial;
430 // Get material lod strategy
431 const LodStrategy *materialStrategy = material->getLodStrategy();
433 // Recalculate lod value if strategies do not match
434 Real biasedMaterialLodValue;
435 if (meshStrategy == materialStrategy)
436 biasedMaterialLodValue = lodValue;
437 else
438 biasedMaterialLodValue = materialStrategy->getValue(this, cam) * materialStrategy->transformBias(mMaterialLodFactor);
440 // Get the index at this biased depth
441 unsigned short idx = material->getLodIndex(biasedMaterialLodValue);
442 // Apply maximum detail restriction (remember lower = higher detail)
443 idx = std::max(mMaxMaterialLodIndex, idx);
444 // Apply minimum detail restriction (remember higher = lower detail)
445 idx = std::min(mMinMaterialLodIndex, idx);
447 // Construct event object
448 EntityMaterialLodChangedEvent evt;
449 evt.subEntity = (*i);
450 evt.camera = cam;
451 evt.lodValue = biasedMaterialLodValue;
452 evt.previousLodIndex = (*i)->mMaterialLodIndex;
453 evt.newLodIndex = idx;
455 // Notify lod event listeners
456 cam->getSceneManager()->_notifyEntityMaterialLodChanged(evt);
458 // Change lod index
459 (*i)->mMaterialLodIndex = evt.newLodIndex;
461 // Also invalidate any camera distance cache
462 (*i)->_invalidateCameraCache ();
467 // Notify any child objects
468 ChildObjectList::iterator child_itr = mChildObjectList.begin();
469 ChildObjectList::iterator child_itr_end = mChildObjectList.end();
470 for( ; child_itr != child_itr_end; child_itr++)
472 (*child_itr).second->_notifyCurrentCamera(cam);
475 //-----------------------------------------------------------------------
476 const AxisAlignedBox& Entity::getBoundingBox(void) const
478 // Get from Mesh
479 mFullBoundingBox = mMesh->getBounds();
480 mFullBoundingBox.merge(getChildObjectsBoundingBox());
482 // Don't scale here, this is taken into account when world BBox calculation is done
484 return mFullBoundingBox;
486 //-----------------------------------------------------------------------
487 AxisAlignedBox Entity::getChildObjectsBoundingBox(void) const
489 AxisAlignedBox aa_box;
490 AxisAlignedBox full_aa_box;
491 full_aa_box.setNull();
493 ChildObjectList::const_iterator child_itr = mChildObjectList.begin();
494 ChildObjectList::const_iterator child_itr_end = mChildObjectList.end();
495 for( ; child_itr != child_itr_end; child_itr++)
497 aa_box = child_itr->second->getBoundingBox();
498 TagPoint* tp = (TagPoint*)child_itr->second->getParentNode();
499 // Use transform local to skeleton since world xform comes later
500 aa_box.transformAffine(tp->_getFullLocalTransform());
502 full_aa_box.merge(aa_box);
505 return full_aa_box;
507 //-----------------------------------------------------------------------
508 const AxisAlignedBox& Entity::getWorldBoundingBox(bool derive) const
510 if (derive)
512 // derive child bounding boxes
513 ChildObjectList::const_iterator child_itr = mChildObjectList.begin();
514 ChildObjectList::const_iterator child_itr_end = mChildObjectList.end();
515 for( ; child_itr != child_itr_end; child_itr++)
517 child_itr->second->getWorldBoundingBox(true);
520 return MovableObject::getWorldBoundingBox(derive);
522 //-----------------------------------------------------------------------
523 const Sphere& Entity::getWorldBoundingSphere(bool derive) const
525 if (derive)
527 // derive child bounding boxes
528 ChildObjectList::const_iterator child_itr = mChildObjectList.begin();
529 ChildObjectList::const_iterator child_itr_end = mChildObjectList.end();
530 for( ; child_itr != child_itr_end; child_itr++)
532 child_itr->second->getWorldBoundingSphere(true);
535 return MovableObject::getWorldBoundingSphere(derive);
538 //-----------------------------------------------------------------------
539 void Entity::_updateRenderQueue(RenderQueue* queue)
541 // Do nothing if not initialised yet
542 if (!mInitialised)
543 return;
545 // Check mesh state count, will be incremented if reloaded
546 if (mMesh->getStateCount() != mMeshStateCount)
548 // force reinitialise
549 _initialise(true);
552 Entity* displayEntity = this;
553 // Check we're not using a manual LOD
554 if (mMeshLodIndex > 0 && mMesh->isLodManual())
556 // Use alternate entity
557 assert( static_cast< size_t >( mMeshLodIndex - 1 ) < mLodEntityList.size() &&
558 "No LOD EntityList - did you build the manual LODs after creating the entity?");
559 // index - 1 as we skip index 0 (original lod)
560 if (hasSkeleton() && mLodEntityList[mMeshLodIndex - 1]->hasSkeleton())
562 // Copy the animation state set to lod entity, we assume the lod
563 // entity only has a subset animation states
564 mAnimationState->copyMatchingState(
565 mLodEntityList[mMeshLodIndex - 1]->mAnimationState);
567 displayEntity = mLodEntityList[mMeshLodIndex - 1];
570 // Add each visible SubEntity to the queue
571 SubEntityList::iterator i, iend;
572 iend = displayEntity->mSubEntityList.end();
573 for (i = displayEntity->mSubEntityList.begin(); i != iend; ++i)
575 if((*i)->isVisible())
577 if(mRenderQueueIDSet)
579 queue->addRenderable(*i, mRenderQueueID);
581 else
583 queue->addRenderable(*i);
588 // Since we know we're going to be rendered, take this opportunity to
589 // update the animation
590 if (displayEntity->hasSkeleton() || displayEntity->hasVertexAnimation())
592 displayEntity->updateAnimation();
594 //--- pass this point, we are sure that the transformation matrix of each bone and tagPoint have been updated
595 ChildObjectList::iterator child_itr = mChildObjectList.begin();
596 ChildObjectList::iterator child_itr_end = mChildObjectList.end();
597 for( ; child_itr != child_itr_end; child_itr++)
599 MovableObject* child = child_itr->second;
600 bool isVisible = child->isVisible();
601 if (isVisible && (displayEntity != this))
603 //Check if the bone exists in the current LOD
605 //The child is connected to a tagpoint which is connected to a bone
606 Bone* bone = static_cast<Bone*>(child->getParentNode()->getParent());
607 if (!displayEntity->getSkeleton()->hasBone(bone->getName()))
609 //Current LOD entity does not have the bone that the
610 //child is connected to. Do not display.
611 isVisible = false;
614 if (isVisible)
616 child->_updateRenderQueue(queue);
621 // HACK to display bones
622 // This won't work if the entity is not centered at the origin
623 // TODO work out a way to allow bones to be rendered when Entity not centered
624 if (mDisplaySkeleton && hasSkeleton())
626 int numBones = mSkeletonInstance->getNumBones();
627 for (int b = 0; b < numBones; ++b)
629 Bone* bone = mSkeletonInstance->getBone(b);
630 if(mRenderQueueIDSet)
632 queue->addRenderable(bone->getDebugRenderable(1), mRenderQueueID);
633 } else {
634 queue->addRenderable(bone->getDebugRenderable(1));
643 //-----------------------------------------------------------------------
644 AnimationState* Entity::getAnimationState(const String& name) const
646 if (!mAnimationState)
648 OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Entity is not animated",
649 "Entity::getAnimationState");
652 return mAnimationState->getAnimationState(name);
654 //-----------------------------------------------------------------------
655 AnimationStateSet* Entity::getAllAnimationStates(void) const
657 return mAnimationState;
659 //-----------------------------------------------------------------------
660 const String& Entity::getMovableType(void) const
662 return EntityFactory::FACTORY_TYPE_NAME;
664 //-----------------------------------------------------------------------
665 bool Entity::tempVertexAnimBuffersBound(void) const
667 // Do we still have temp buffers for software vertex animation bound?
668 bool ret = true;
669 if (mMesh->sharedVertexData && mMesh->getSharedVertexDataAnimationType() != VAT_NONE)
671 ret = ret && mTempVertexAnimInfo.buffersCheckedOut(true, false);
673 for (SubEntityList::const_iterator i = mSubEntityList.begin();
674 i != mSubEntityList.end(); ++i)
676 SubEntity* sub = *i;
677 if (!sub->getSubMesh()->useSharedVertices
678 && sub->getSubMesh()->getVertexAnimationType() != VAT_NONE)
680 ret = ret && sub->_getVertexAnimTempBufferInfo()->buffersCheckedOut(true, false);
683 return ret;
685 //-----------------------------------------------------------------------
686 bool Entity::tempSkelAnimBuffersBound(bool requestNormals) const
688 // Do we still have temp buffers for software skeleton animation bound?
689 if (mSkelAnimVertexData)
691 if (!mTempSkelAnimInfo.buffersCheckedOut(true, requestNormals))
692 return false;
694 for (SubEntityList::const_iterator i = mSubEntityList.begin();
695 i != mSubEntityList.end(); ++i)
697 SubEntity* sub = *i;
698 if (sub->isVisible() && sub->mSkelAnimVertexData)
700 if (!sub->mTempSkelAnimInfo.buffersCheckedOut(true, requestNormals))
701 return false;
704 return true;
706 //-----------------------------------------------------------------------
707 void Entity::updateAnimation(void)
709 // Do nothing if not initialised yet
710 if (!mInitialised)
711 return;
713 Root& root = Root::getSingleton();
714 bool hwAnimation = isHardwareAnimationEnabled();
715 bool forcedSwAnimation = getSoftwareAnimationRequests()>0;
716 bool forcedNormals = getSoftwareAnimationNormalsRequests()>0;
717 bool stencilShadows = false;
718 if (getCastShadows() && hasEdgeList() && root._getCurrentSceneManager())
719 stencilShadows = root._getCurrentSceneManager()->isShadowTechniqueStencilBased();
720 bool softwareAnimation = !hwAnimation || stencilShadows || forcedSwAnimation;
721 // Blend normals in s/w only if we're not using h/w animation,
722 // since shadows only require positions
723 bool blendNormals = !hwAnimation || forcedNormals;
724 // Animation dirty if animation state modified or manual bones modified
725 bool animationDirty =
726 (mFrameAnimationLastUpdated != mAnimationState->getDirtyFrameNumber()) ||
727 (hasSkeleton() && getSkeleton()->getManualBonesDirty());
729 // We only do these tasks if animation is dirty
730 // Or, if we're using a skeleton and manual bones have been moved
731 // Or, if we're using software animation and temp buffers are unbound
732 if (animationDirty ||
733 (softwareAnimation && hasVertexAnimation() && !tempVertexAnimBuffersBound()) ||
734 (softwareAnimation && hasSkeleton() && !tempSkelAnimBuffersBound(blendNormals)))
736 if (hasVertexAnimation())
738 if (softwareAnimation)
740 // grab & bind temporary buffer for positions
741 if (mSoftwareVertexAnimVertexData
742 && mMesh->getSharedVertexDataAnimationType() != VAT_NONE)
744 mTempVertexAnimInfo.checkoutTempCopies(true, false);
745 // NB we suppress hardware upload while doing blend if we're
746 // hardware animation, because the only reason for doing this
747 // is for shadow, which need only be uploaded then
748 mTempVertexAnimInfo.bindTempCopies(mSoftwareVertexAnimVertexData,
749 hwAnimation);
751 SubEntityList::iterator i, iend;
752 iend = mSubEntityList.end();
753 for (i = mSubEntityList.begin(); i != iend; ++i)
755 // Blend dedicated geometry
756 SubEntity* se = *i;
757 if (se->isVisible() && se->mSoftwareVertexAnimVertexData
758 && se->getSubMesh()->getVertexAnimationType() != VAT_NONE)
760 se->mTempVertexAnimInfo.checkoutTempCopies(true, false);
761 se->mTempVertexAnimInfo.bindTempCopies(se->mSoftwareVertexAnimVertexData,
762 hwAnimation);
767 applyVertexAnimation(hwAnimation, stencilShadows);
770 if (hasSkeleton())
772 cacheBoneMatrices();
774 // Software blend?
775 if (softwareAnimation)
777 const Matrix4* blendMatrices[256];
779 // Ok, we need to do a software blend
780 // Firstly, check out working vertex buffers
781 if (mSkelAnimVertexData)
783 // Blend shared geometry
784 // NB we suppress hardware upload while doing blend if we're
785 // hardware animation, because the only reason for doing this
786 // is for shadow, which need only be uploaded then
787 mTempSkelAnimInfo.checkoutTempCopies(true, blendNormals);
788 mTempSkelAnimInfo.bindTempCopies(mSkelAnimVertexData,
789 hwAnimation);
790 // Prepare blend matrices, TODO: Move out of here
791 Mesh::prepareMatricesForVertexBlend(blendMatrices,
792 mBoneMatrices, mMesh->sharedBlendIndexToBoneIndexMap);
793 // Blend, taking source from either mesh data or morph data
794 Mesh::softwareVertexBlend(
795 (mMesh->getSharedVertexDataAnimationType() != VAT_NONE) ?
796 mSoftwareVertexAnimVertexData : mMesh->sharedVertexData,
797 mSkelAnimVertexData,
798 blendMatrices, mMesh->sharedBlendIndexToBoneIndexMap.size(),
799 blendNormals);
801 SubEntityList::iterator i, iend;
802 iend = mSubEntityList.end();
803 for (i = mSubEntityList.begin(); i != iend; ++i)
805 // Blend dedicated geometry
806 SubEntity* se = *i;
807 if (se->isVisible() && se->mSkelAnimVertexData)
809 se->mTempSkelAnimInfo.checkoutTempCopies(true, blendNormals);
810 se->mTempSkelAnimInfo.bindTempCopies(se->mSkelAnimVertexData,
811 hwAnimation);
812 // Prepare blend matrices, TODO: Move out of here
813 Mesh::prepareMatricesForVertexBlend(blendMatrices,
814 mBoneMatrices, se->mSubMesh->blendIndexToBoneIndexMap);
815 // Blend, taking source from either mesh data or morph data
816 Mesh::softwareVertexBlend(
817 (se->getSubMesh()->getVertexAnimationType() != VAT_NONE)?
818 se->mSoftwareVertexAnimVertexData : se->mSubMesh->vertexData,
819 se->mSkelAnimVertexData,
820 blendMatrices, se->mSubMesh->blendIndexToBoneIndexMap.size(),
821 blendNormals);
829 // Trigger update of bounding box if necessary
830 if (!mChildObjectList.empty())
831 mParentNode->needUpdate();
833 mFrameAnimationLastUpdated = mAnimationState->getDirtyFrameNumber();
836 // Need to update the child object's transforms when animation dirty
837 // or parent node transform has altered.
838 if (hasSkeleton() &&
839 (animationDirty || mLastParentXform != _getParentNodeFullTransform()))
841 // Cache last parent transform for next frame use too.
842 mLastParentXform = _getParentNodeFullTransform();
844 //--- Update the child object's transforms
845 ChildObjectList::iterator child_itr = mChildObjectList.begin();
846 ChildObjectList::iterator child_itr_end = mChildObjectList.end();
847 for( ; child_itr != child_itr_end; child_itr++)
849 (*child_itr).second->getParentNode()->_update(true, true);
852 // Also calculate bone world matrices, since are used as replacement world matrices,
853 // but only if it's used (when using hardware animation and skeleton animated).
854 if (hwAnimation && _isSkeletonAnimated())
856 // Allocate bone world matrices on demand, for better memory footprint
857 // when using software animation.
858 if (!mBoneWorldMatrices)
860 mBoneWorldMatrices =
861 static_cast<Matrix4*>(OGRE_MALLOC_SIMD(sizeof(Matrix4) * mNumBoneMatrices, MEMCATEGORY_ANIMATION));
864 OptimisedUtil::getImplementation()->concatenateAffineMatrices(
865 mLastParentXform,
866 mBoneMatrices,
867 mBoneWorldMatrices,
868 mNumBoneMatrices);
872 //-----------------------------------------------------------------------
873 void Entity::initHardwareAnimationElements(VertexData* vdata,
874 ushort numberOfElements)
876 if (vdata->hwAnimationDataList.size() < numberOfElements)
878 vdata->allocateHardwareAnimationElements(numberOfElements);
880 // Initialise parametrics incase we don't use all of them
881 for (size_t i = 0; i < vdata->hwAnimationDataList.size(); ++i)
883 vdata->hwAnimationDataList[i].parametric = 0.0f;
885 // reset used count
886 vdata->hwAnimDataItemsUsed = 0;
889 //-----------------------------------------------------------------------
890 void Entity::applyVertexAnimation(bool hardwareAnimation, bool stencilShadows)
892 const MeshPtr& msh = getMesh();
893 bool swAnim = !hardwareAnimation || stencilShadows || (mSoftwareAnimationRequests>0);
895 // make sure we have enough hardware animation elements to play with
896 if (hardwareAnimation)
898 if (mHardwareVertexAnimVertexData
899 && msh->getSharedVertexDataAnimationType() != VAT_NONE)
901 initHardwareAnimationElements(mHardwareVertexAnimVertexData,
902 (msh->getSharedVertexDataAnimationType() == VAT_POSE)
903 ? mHardwarePoseCount : 1);
905 for (SubEntityList::iterator si = mSubEntityList.begin();
906 si != mSubEntityList.end(); ++si)
908 SubEntity* sub = *si;
909 if (sub->getSubMesh()->getVertexAnimationType() != VAT_NONE &&
910 !sub->getSubMesh()->useSharedVertices)
912 initHardwareAnimationElements(
913 sub->_getHardwareVertexAnimVertexData(),
914 (sub->getSubMesh()->getVertexAnimationType() == VAT_POSE)
915 ? sub->mHardwarePoseCount : 1);
920 else
922 // May be blending multiple poses in software
923 // Suppress hardware upload of buffers
924 if (mSoftwareVertexAnimVertexData &&
925 mMesh->getSharedVertexDataAnimationType() == VAT_POSE)
927 const VertexElement* elem = mSoftwareVertexAnimVertexData
928 ->vertexDeclaration->findElementBySemantic(VES_POSITION);
929 HardwareVertexBufferSharedPtr buf = mSoftwareVertexAnimVertexData
930 ->vertexBufferBinding->getBuffer(elem->getSource());
931 buf->suppressHardwareUpdate(true);
933 for (SubEntityList::iterator si = mSubEntityList.begin();
934 si != mSubEntityList.end(); ++si)
936 SubEntity* sub = *si;
937 if (!sub->getSubMesh()->useSharedVertices &&
938 sub->getSubMesh()->getVertexAnimationType() == VAT_POSE)
940 VertexData* data = sub->_getSoftwareVertexAnimVertexData();
941 const VertexElement* elem = data->vertexDeclaration
942 ->findElementBySemantic(VES_POSITION);
943 HardwareVertexBufferSharedPtr buf = data
944 ->vertexBufferBinding->getBuffer(elem->getSource());
945 buf->suppressHardwareUpdate(true);
951 // Now apply the animation(s)
952 // Note - you should only apply one morph animation to each set of vertex data
953 // at once; if you do more, only the last one will actually apply
954 markBuffersUnusedForAnimation();
955 ConstEnabledAnimationStateIterator animIt = mAnimationState->getEnabledAnimationStateIterator();
956 while(animIt.hasMoreElements())
958 const AnimationState* state = animIt.getNext();
959 Animation* anim = msh->_getAnimationImpl(state->getAnimationName());
960 if (anim)
962 anim->apply(this, state->getTimePosition(), state->getWeight(),
963 swAnim, hardwareAnimation);
966 // Deal with cases where no animation applied
967 restoreBuffersForUnusedAnimation(hardwareAnimation);
969 // Unsuppress hardware upload if we suppressed it
970 if (!hardwareAnimation)
972 if (mSoftwareVertexAnimVertexData &&
973 msh->getSharedVertexDataAnimationType() == VAT_POSE)
975 const VertexElement* elem = mSoftwareVertexAnimVertexData
976 ->vertexDeclaration->findElementBySemantic(VES_POSITION);
977 HardwareVertexBufferSharedPtr buf = mSoftwareVertexAnimVertexData
978 ->vertexBufferBinding->getBuffer(elem->getSource());
979 buf->suppressHardwareUpdate(false);
981 for (SubEntityList::iterator si = mSubEntityList.begin();
982 si != mSubEntityList.end(); ++si)
984 SubEntity* sub = *si;
985 if (!sub->getSubMesh()->useSharedVertices &&
986 sub->getSubMesh()->getVertexAnimationType() == VAT_POSE)
988 VertexData* data = sub->_getSoftwareVertexAnimVertexData();
989 const VertexElement* elem = data->vertexDeclaration
990 ->findElementBySemantic(VES_POSITION);
991 HardwareVertexBufferSharedPtr buf = data
992 ->vertexBufferBinding->getBuffer(elem->getSource());
993 buf->suppressHardwareUpdate(false);
999 //-----------------------------------------------------------------------------
1000 void Entity::markBuffersUnusedForAnimation(void)
1002 mVertexAnimationAppliedThisFrame = false;
1003 for (SubEntityList::iterator i = mSubEntityList.begin();
1004 i != mSubEntityList.end(); ++i)
1006 (*i)->_markBuffersUnusedForAnimation();
1009 //-----------------------------------------------------------------------------
1010 void Entity::_markBuffersUsedForAnimation(void)
1012 mVertexAnimationAppliedThisFrame = true;
1013 // no cascade
1015 //-----------------------------------------------------------------------------
1016 void Entity::restoreBuffersForUnusedAnimation(bool hardwareAnimation)
1018 // Rebind original positions if:
1019 // We didn't apply any animation and
1020 // We're morph animated (hardware binds keyframe, software is missing)
1021 // or we're pose animated and software (hardware is fine, still bound)
1022 if (mMesh->sharedVertexData &&
1023 !mVertexAnimationAppliedThisFrame &&
1024 (!hardwareAnimation || mMesh->getSharedVertexDataAnimationType() == VAT_MORPH))
1026 const VertexElement* srcPosElem =
1027 mMesh->sharedVertexData->vertexDeclaration->findElementBySemantic(VES_POSITION);
1028 HardwareVertexBufferSharedPtr srcBuf =
1029 mMesh->sharedVertexData->vertexBufferBinding->getBuffer(
1030 srcPosElem->getSource());
1032 // Bind to software
1033 const VertexElement* destPosElem =
1034 mSoftwareVertexAnimVertexData->vertexDeclaration->findElementBySemantic(VES_POSITION);
1035 mSoftwareVertexAnimVertexData->vertexBufferBinding->setBinding(
1036 destPosElem->getSource(), srcBuf);
1040 // rebind any missing hardware pose buffers
1041 // Caused by not having any animations enabled, or keyframes which reference
1042 // no poses
1043 if (mMesh->sharedVertexData && hardwareAnimation
1044 && mMesh->getSharedVertexDataAnimationType() == VAT_POSE)
1046 bindMissingHardwarePoseBuffers(mMesh->sharedVertexData, mHardwareVertexAnimVertexData);
1050 for (SubEntityList::iterator i = mSubEntityList.begin();
1051 i != mSubEntityList.end(); ++i)
1053 (*i)->_restoreBuffersForUnusedAnimation(hardwareAnimation);
1057 //---------------------------------------------------------------------
1058 void Entity::bindMissingHardwarePoseBuffers(const VertexData* srcData,
1059 VertexData* destData)
1061 // For hardware pose animation, also make sure we've bound buffers to all the elements
1062 // required - if there are missing bindings for elements in use,
1063 // some rendersystems can complain because elements refer
1064 // to an unbound source.
1065 // Get the original position source, we'll use this to fill gaps
1066 const VertexElement* srcPosElem =
1067 srcData->vertexDeclaration->findElementBySemantic(VES_POSITION);
1068 HardwareVertexBufferSharedPtr srcBuf =
1069 srcData->vertexBufferBinding->getBuffer(
1070 srcPosElem->getSource());
1072 for (VertexData::HardwareAnimationDataList::const_iterator i = destData->hwAnimationDataList.begin();
1073 i != destData->hwAnimationDataList.end(); ++i)
1075 const VertexData::HardwareAnimationData& animData = *i;
1076 if (!destData->vertexBufferBinding->isBufferBound(
1077 animData.targetVertexElement->getSource()))
1079 // Bind to a safe default
1080 destData->vertexBufferBinding->setBinding(
1081 animData.targetVertexElement->getSource(), srcBuf);
1086 //-----------------------------------------------------------------------
1087 void Entity::_updateAnimation(void)
1089 // Externally visible method
1090 if (hasSkeleton() || hasVertexAnimation())
1092 updateAnimation();
1095 //-----------------------------------------------------------------------
1096 bool Entity::_isAnimated(void) const
1098 return (mAnimationState && mAnimationState->hasEnabledAnimationState()) ||
1099 (getSkeleton() && getSkeleton()->hasManualBones());
1101 //-----------------------------------------------------------------------
1102 bool Entity::_isSkeletonAnimated(void) const
1104 return getSkeleton() &&
1105 (mAnimationState->hasEnabledAnimationState() || getSkeleton()->hasManualBones());
1107 //-----------------------------------------------------------------------
1108 VertexData* Entity::_getSkelAnimVertexData(void) const
1110 assert (mSkelAnimVertexData && "Not software skinned or has no shared vertex data!");
1111 return mSkelAnimVertexData;
1113 //-----------------------------------------------------------------------
1114 VertexData* Entity::_getSoftwareVertexAnimVertexData(void) const
1116 assert (mSoftwareVertexAnimVertexData && "Not vertex animated or has no shared vertex data!");
1117 return mSoftwareVertexAnimVertexData;
1119 //-----------------------------------------------------------------------
1120 VertexData* Entity::_getHardwareVertexAnimVertexData(void) const
1122 assert (mHardwareVertexAnimVertexData && "Not vertex animated or has no shared vertex data!");
1123 return mHardwareVertexAnimVertexData;
1125 //-----------------------------------------------------------------------
1126 TempBlendedBufferInfo* Entity::_getSkelAnimTempBufferInfo(void)
1128 return &mTempSkelAnimInfo;
1130 //-----------------------------------------------------------------------
1131 TempBlendedBufferInfo* Entity::_getVertexAnimTempBufferInfo(void)
1133 return &mTempVertexAnimInfo;
1135 //-----------------------------------------------------------------------
1136 void Entity::cacheBoneMatrices(void)
1138 Root& root = Root::getSingleton();
1139 unsigned long currentFrameNumber = root.getNextFrameNumber();
1140 if (*mFrameBonesLastUpdated != currentFrameNumber) {
1142 mSkeletonInstance->setAnimationState(*mAnimationState);
1143 mSkeletonInstance->_getBoneMatrices(mBoneMatrices);
1144 *mFrameBonesLastUpdated = currentFrameNumber;
1147 //-----------------------------------------------------------------------
1148 void Entity::setDisplaySkeleton(bool display)
1150 mDisplaySkeleton = display;
1152 //-----------------------------------------------------------------------
1153 bool Entity::getDisplaySkeleton(void) const
1155 return mDisplaySkeleton;
1157 //-----------------------------------------------------------------------
1158 Entity* Entity::getManualLodLevel(size_t index) const
1160 assert(index < mLodEntityList.size());
1162 return mLodEntityList[index];
1164 //-----------------------------------------------------------------------
1165 size_t Entity::getNumManualLodLevels(void) const
1167 return mLodEntityList.size();
1169 //-----------------------------------------------------------------------
1170 void Entity::setMeshLodBias(Real factor, ushort maxDetailIndex, ushort minDetailIndex)
1172 mMeshLodFactorTransformed = mMesh->getLodStrategy()->transformBias(factor);
1173 mMaxMeshLodIndex = maxDetailIndex;
1174 mMinMeshLodIndex = minDetailIndex;
1177 //-----------------------------------------------------------------------
1178 void Entity::setMaterialLodBias(Real factor, ushort maxDetailIndex, ushort minDetailIndex)
1180 mMaterialLodFactor = factor;
1181 mMaterialLodFactorTransformed = mMesh->getLodStrategy()->transformBias(factor);
1182 mMaxMaterialLodIndex = maxDetailIndex;
1183 mMinMaterialLodIndex = minDetailIndex;
1186 //-----------------------------------------------------------------------
1187 void Entity::buildSubEntityList(MeshPtr& mesh, SubEntityList* sublist)
1189 // Create SubEntities
1190 unsigned short i, numSubMeshes;
1191 SubMesh* subMesh;
1192 SubEntity* subEnt;
1194 numSubMeshes = mesh->getNumSubMeshes();
1195 for (i = 0; i < numSubMeshes; ++i)
1197 subMesh = mesh->getSubMesh(i);
1198 subEnt = OGRE_NEW SubEntity(this, subMesh);
1199 if (subMesh->isMatInitialised())
1200 subEnt->setMaterialName(subMesh->getMaterialName(), mesh->getGroup());
1201 sublist->push_back(subEnt);
1204 //-----------------------------------------------------------------------
1205 void Entity::setPolygonModeOverrideable(bool overrideable)
1207 SubEntityList::iterator i, iend;
1208 iend = mSubEntityList.end();
1210 for( i = mSubEntityList.begin(); i != iend; ++i )
1212 (*i)->setPolygonModeOverrideable(overrideable);
1216 //-----------------------------------------------------------------------
1217 TagPoint* Entity::attachObjectToBone(const String &boneName, MovableObject *pMovable, const Quaternion &offsetOrientation, const Vector3 &offsetPosition)
1219 if (mChildObjectList.find(pMovable->getName()) != mChildObjectList.end())
1221 OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM,
1222 "An object with the name " + pMovable->getName() + " already attached",
1223 "Entity::attachObjectToBone");
1225 if(pMovable->isAttached())
1227 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Object already attached to a sceneNode or a Bone",
1228 "Entity::attachObjectToBone");
1230 if (!hasSkeleton())
1232 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "This entity's mesh has no skeleton to attach object to.",
1233 "Entity::attachObjectToBone");
1235 Bone* bone = mSkeletonInstance->getBone(boneName);
1236 if (!bone)
1238 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot locate bone named " + boneName,
1239 "Entity::attachObjectToBone");
1242 TagPoint *tp = mSkeletonInstance->createTagPointOnBone(
1243 bone, offsetOrientation, offsetPosition);
1244 tp->setParentEntity(this);
1245 tp->setChildObject(pMovable);
1247 attachObjectImpl(pMovable, tp);
1249 // Trigger update of bounding box if necessary
1250 if (mParentNode)
1251 mParentNode->needUpdate();
1253 return tp;
1256 //-----------------------------------------------------------------------
1257 void Entity::attachObjectImpl(MovableObject *pObject, TagPoint *pAttachingPoint)
1259 assert(mChildObjectList.find(pObject->getName()) == mChildObjectList.end());
1260 mChildObjectList[pObject->getName()] = pObject;
1261 pObject->_notifyAttached(pAttachingPoint, true);
1264 //-----------------------------------------------------------------------
1265 MovableObject* Entity::detachObjectFromBone(const String &name)
1267 ChildObjectList::iterator i = mChildObjectList.find(name);
1269 if (i == mChildObjectList.end())
1271 OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "No child object entry found named " + name,
1272 "Entity::detachObjectFromBone");
1274 MovableObject *obj = i->second;
1275 detachObjectImpl(obj);
1276 mChildObjectList.erase(i);
1278 // Trigger update of bounding box if necessary
1279 if (mParentNode)
1280 mParentNode->needUpdate();
1282 return obj;
1284 //-----------------------------------------------------------------------
1285 void Entity::detachObjectFromBone(MovableObject* obj)
1287 ChildObjectList::iterator i, iend;
1288 iend = mChildObjectList.end();
1289 for (i = mChildObjectList.begin(); i != iend; ++i)
1291 if (i->second == obj)
1293 detachObjectImpl(obj);
1294 mChildObjectList.erase(i);
1296 // Trigger update of bounding box if necessary
1297 if (mParentNode)
1298 mParentNode->needUpdate();
1299 break;
1303 //-----------------------------------------------------------------------
1304 void Entity::detachAllObjectsFromBone(void)
1306 detachAllObjectsImpl();
1308 // Trigger update of bounding box if necessary
1309 if (mParentNode)
1310 mParentNode->needUpdate();
1312 //-----------------------------------------------------------------------
1313 void Entity::detachObjectImpl(MovableObject* pObject)
1315 TagPoint* tp = static_cast<TagPoint*>(pObject->getParentNode());
1317 // free the TagPoint so we can reuse it later
1318 mSkeletonInstance->freeTagPoint(tp);
1320 pObject->_notifyAttached((TagPoint*)0);
1322 //-----------------------------------------------------------------------
1323 void Entity::detachAllObjectsImpl(void)
1325 ChildObjectList::const_iterator i, iend;
1326 iend = mChildObjectList.end();
1327 for (i = mChildObjectList.begin(); i != iend; ++i)
1329 detachObjectImpl(i->second);
1331 mChildObjectList.clear();
1334 //-----------------------------------------------------------------------
1335 Entity::ChildObjectListIterator Entity::getAttachedObjectIterator()
1337 return ChildObjectListIterator(mChildObjectList.begin(), mChildObjectList.end());
1339 //-----------------------------------------------------------------------
1340 Real Entity::getBoundingRadius(void) const
1342 Real rad = mMesh->getBoundingSphereRadius();
1343 // Scale by largest scale factor
1344 if (mParentNode)
1346 const Vector3& s = mParentNode->_getDerivedScale();
1347 rad *= std::max(s.x, std::max(s.y, s.z));
1349 return rad;
1351 //-----------------------------------------------------------------------
1352 void Entity::prepareTempBlendBuffers(void)
1354 if (mSkelAnimVertexData)
1356 OGRE_DELETE mSkelAnimVertexData;
1357 mSkelAnimVertexData = 0;
1359 if (mSoftwareVertexAnimVertexData)
1361 OGRE_DELETE mSoftwareVertexAnimVertexData;
1362 mSoftwareVertexAnimVertexData = 0;
1364 if (mHardwareVertexAnimVertexData)
1366 OGRE_DELETE mHardwareVertexAnimVertexData;
1367 mHardwareVertexAnimVertexData = 0;
1370 if (hasVertexAnimation())
1372 // Shared data
1373 if (mMesh->sharedVertexData
1374 && mMesh->getSharedVertexDataAnimationType() != VAT_NONE)
1376 // Create temporary vertex blend info
1377 // Prepare temp vertex data if needed
1378 // Clone without copying data, don't remove any blending info
1379 // (since if we skeletally animate too, we need it)
1380 mSoftwareVertexAnimVertexData = mMesh->sharedVertexData->clone(false);
1381 extractTempBufferInfo(mSoftwareVertexAnimVertexData, &mTempVertexAnimInfo);
1383 // Also clone for hardware usage, don't remove blend info since we'll
1384 // need it if we also hardware skeletally animate
1385 mHardwareVertexAnimVertexData = mMesh->sharedVertexData->clone(false);
1389 if (hasSkeleton())
1391 // Shared data
1392 if (mMesh->sharedVertexData)
1394 // Create temporary vertex blend info
1395 // Prepare temp vertex data if needed
1396 // Clone without copying data, remove blending info
1397 // (since blend is performed in software)
1398 mSkelAnimVertexData =
1399 cloneVertexDataRemoveBlendInfo(mMesh->sharedVertexData);
1400 extractTempBufferInfo(mSkelAnimVertexData, &mTempSkelAnimInfo);
1405 // Do SubEntities
1406 SubEntityList::iterator i, iend;
1407 iend = mSubEntityList.end();
1408 for (i = mSubEntityList.begin(); i != iend; ++i)
1410 SubEntity* s = *i;
1411 s->prepareTempBlendBuffers();
1414 // It's prepared for shadow volumes only if mesh has been prepared for shadow volumes.
1415 mPreparedForShadowVolumes = mMesh->isPreparedForShadowVolumes();
1417 //-----------------------------------------------------------------------
1418 void Entity::extractTempBufferInfo(VertexData* sourceData, TempBlendedBufferInfo* info)
1420 info->extractFrom(sourceData);
1422 //-----------------------------------------------------------------------
1423 VertexData* Entity::cloneVertexDataRemoveBlendInfo(const VertexData* source)
1425 // Clone without copying data
1426 VertexData* ret = source->clone(false);
1427 const VertexElement* blendIndexElem =
1428 source->vertexDeclaration->findElementBySemantic(VES_BLEND_INDICES);
1429 const VertexElement* blendWeightElem =
1430 source->vertexDeclaration->findElementBySemantic(VES_BLEND_WEIGHTS);
1431 // Remove blend index
1432 if (blendIndexElem)
1434 // Remove buffer reference
1435 ret->vertexBufferBinding->unsetBinding(blendIndexElem->getSource());
1438 if (blendWeightElem &&
1439 blendWeightElem->getSource() != blendIndexElem->getSource())
1441 // Remove buffer reference
1442 ret->vertexBufferBinding->unsetBinding(blendWeightElem->getSource());
1444 // remove elements from declaration
1445 ret->vertexDeclaration->removeElement(VES_BLEND_INDICES);
1446 ret->vertexDeclaration->removeElement(VES_BLEND_WEIGHTS);
1448 // Close gaps in bindings for effective and safely
1449 ret->closeGapsInBindings();
1451 return ret;
1453 //-----------------------------------------------------------------------
1454 EdgeData* Entity::getEdgeList(void)
1456 // Get from Mesh
1457 return mMesh->getEdgeList(mMeshLodIndex);
1459 //-----------------------------------------------------------------------
1460 bool Entity::hasEdgeList(void)
1462 // check if mesh has an edge list attached
1463 // give mesh a chance to built it if scheduled
1464 return (mMesh->getEdgeList(mMeshLodIndex) != NULL);
1466 //-----------------------------------------------------------------------
1467 void Entity::reevaluateVertexProcessing(void)
1469 // init
1470 mHardwareAnimation = false;
1471 mVertexProgramInUse = false; // assume false because we just assign this
1472 bool firstPass = true;
1474 SubEntityList::iterator i, iend;
1475 iend = mSubEntityList.end();
1476 for (i = mSubEntityList.begin(); i != iend; ++i)
1478 SubEntity* sub = *i;
1479 const MaterialPtr& m = sub->getMaterial();
1480 // Make sure it's loaded
1481 m->load();
1482 Technique* t = m->getBestTechnique(0, sub);
1483 if (!t)
1485 // No supported techniques
1486 continue;
1488 if (t->getNumPasses() == 0)
1490 // No passes, invalid
1491 continue;
1493 Pass* p = t->getPass(0);
1494 if (p->hasVertexProgram())
1496 // If one material uses a vertex program, set this flag
1497 // Causes some special processing like forcing a separate light cap
1498 mVertexProgramInUse = true;
1500 if (hasSkeleton())
1502 // All materials must support skinning for us to consider using
1503 // hardware animation - if one fails we use software
1504 if (firstPass)
1506 mHardwareAnimation = p->getVertexProgram()->isSkeletalAnimationIncluded();
1507 firstPass = false;
1509 else
1511 mHardwareAnimation = mHardwareAnimation &&
1512 p->getVertexProgram()->isSkeletalAnimationIncluded();
1516 VertexAnimationType animType = VAT_NONE;
1517 if (sub->getSubMesh()->useSharedVertices)
1519 animType = mMesh->getSharedVertexDataAnimationType();
1521 else
1523 animType = sub->getSubMesh()->getVertexAnimationType();
1525 if (animType == VAT_MORPH)
1527 // All materials must support morph animation for us to consider using
1528 // hardware animation - if one fails we use software
1529 if (firstPass)
1531 mHardwareAnimation = p->getVertexProgram()->isMorphAnimationIncluded();
1532 firstPass = false;
1534 else
1536 mHardwareAnimation = mHardwareAnimation &&
1537 p->getVertexProgram()->isMorphAnimationIncluded();
1540 else if (animType == VAT_POSE)
1542 // All materials must support pose animation for us to consider using
1543 // hardware animation - if one fails we use software
1544 if (firstPass)
1546 mHardwareAnimation = p->getVertexProgram()->isPoseAnimationIncluded();
1547 if (sub->getSubMesh()->useSharedVertices)
1548 mHardwarePoseCount = p->getVertexProgram()->getNumberOfPosesIncluded();
1549 else
1550 sub->mHardwarePoseCount = p->getVertexProgram()->getNumberOfPosesIncluded();
1551 firstPass = false;
1553 else
1555 mHardwareAnimation = mHardwareAnimation &&
1556 p->getVertexProgram()->isPoseAnimationIncluded();
1557 if (sub->getSubMesh()->useSharedVertices)
1558 mHardwarePoseCount = std::max(mHardwarePoseCount,
1559 p->getVertexProgram()->getNumberOfPosesIncluded());
1560 else
1561 sub->mHardwarePoseCount = std::max(sub->mHardwarePoseCount,
1562 p->getVertexProgram()->getNumberOfPosesIncluded());
1569 // Should be force update of animation if they exists, due reevaluate
1570 // vertex processing might switchs between hardware/software animation,
1571 // and then we'll end with NULL or incorrect mBoneWorldMatrices, or
1572 // incorrect blended software animation buffers.
1573 if (mAnimationState)
1575 mFrameAnimationLastUpdated = mAnimationState->getDirtyFrameNumber() - 1;
1578 //-----------------------------------------------------------------------
1579 Real Entity::_getMeshLodFactorTransformed() const
1581 return mMeshLodFactorTransformed;
1583 //-----------------------------------------------------------------------
1584 ShadowCaster::ShadowRenderableListIterator
1585 Entity::getShadowVolumeRenderableIterator(
1586 ShadowTechnique shadowTechnique, const Light* light,
1587 HardwareIndexBufferSharedPtr* indexBuffer,
1588 bool extrude, Real extrusionDistance, unsigned long flags)
1590 assert(indexBuffer && "Only external index buffers are supported right now");
1591 assert((*indexBuffer)->getType() == HardwareIndexBuffer::IT_16BIT &&
1592 "Only 16-bit indexes supported for now");
1594 // Potentially delegate to LOD entity
1595 if (mMesh->isLodManual() && mMeshLodIndex > 0)
1597 // Use alternate entity
1598 assert( static_cast< size_t >( mMeshLodIndex - 1 ) < mLodEntityList.size() &&
1599 "No LOD EntityList - did you build the manual LODs after creating the entity?");
1600 // delegate, we're using manual LOD and not the top lod index
1601 if (hasSkeleton() && mLodEntityList[mMeshLodIndex - 1]->hasSkeleton())
1603 // Copy the animation state set to lod entity, we assume the lod
1604 // entity only has a subset animation states
1605 mAnimationState->copyMatchingState(
1606 mLodEntityList[mMeshLodIndex - 1]->mAnimationState);
1608 return mLodEntityList[mMeshLodIndex-1]->getShadowVolumeRenderableIterator(
1609 shadowTechnique, light, indexBuffer, extrude,
1610 extrusionDistance, flags);
1614 // Prepare temp buffers if required
1615 if (!mPreparedForShadowVolumes)
1617 mMesh->prepareForShadowVolume();
1618 // reset frame last updated to force update of animations if they exist
1619 if (mAnimationState)
1620 mFrameAnimationLastUpdated = mAnimationState->getDirtyFrameNumber() - 1;
1621 // re-prepare buffers
1622 prepareTempBlendBuffers();
1626 bool hasAnimation = (hasSkeleton() || hasVertexAnimation());
1628 // Update any animation
1629 if (hasAnimation)
1631 updateAnimation();
1634 // Calculate the object space light details
1635 Vector4 lightPos = light->getAs4DVector();
1636 Matrix4 world2Obj = mParentNode->_getFullTransform().inverseAffine();
1637 lightPos = world2Obj.transformAffine(lightPos);
1639 // We need to search the edge list for silhouette edges
1640 EdgeData* edgeList = getEdgeList();
1642 if (!edgeList)
1644 // we can't get an edge list for some reason, return blank
1645 // really we shouldn't be able to get here, but this is a safeguard
1646 return ShadowRenderableListIterator(mShadowRenderables.begin(), mShadowRenderables.end());
1649 // Init shadow renderable list if required
1650 bool init = mShadowRenderables.empty();
1652 EdgeData::EdgeGroupList::iterator egi;
1653 ShadowRenderableList::iterator si, siend;
1654 EntityShadowRenderable* esr = 0;
1655 if (init)
1656 mShadowRenderables.resize(edgeList->edgeGroups.size());
1658 bool isAnimated = hasAnimation;
1659 bool updatedSharedGeomNormals = false;
1660 siend = mShadowRenderables.end();
1661 egi = edgeList->edgeGroups.begin();
1662 for (si = mShadowRenderables.begin(); si != siend; ++si, ++egi)
1664 const VertexData *pVertData;
1665 if (isAnimated)
1667 // Use temp buffers
1668 pVertData = findBlendedVertexData(egi->vertexData);
1670 else
1672 pVertData = egi->vertexData;
1674 if (init)
1676 // Try to find corresponding SubEntity; this allows the
1677 // linkage of visibility between ShadowRenderable and SubEntity
1678 SubEntity* subent = findSubEntityForVertexData(egi->vertexData);
1679 // Create a new renderable, create a separate light cap if
1680 // we're using a vertex program (either for this model, or
1681 // for extruding the shadow volume) since otherwise we can
1682 // get depth-fighting on the light cap
1684 *si = OGRE_NEW EntityShadowRenderable(this, indexBuffer, pVertData,
1685 mVertexProgramInUse || !extrude, subent);
1687 else
1689 // If we have animation, we have no guarantee that the position
1690 // buffer we used last frame is the same one we used last frame
1691 // since a temporary buffer is requested each frame
1692 // therefore, we need to update the EntityShadowRenderable
1693 // with the current position buffer
1694 static_cast<EntityShadowRenderable*>(*si)->rebindPositionBuffer(pVertData, hasAnimation);
1697 // Get shadow renderable
1698 esr = static_cast<EntityShadowRenderable*>(*si);
1699 HardwareVertexBufferSharedPtr esrPositionBuffer = esr->getPositionBuffer();
1700 // For animated entities we need to recalculate the face normals
1701 if (hasAnimation)
1703 if (egi->vertexData != mMesh->sharedVertexData || !updatedSharedGeomNormals)
1705 // recalculate face normals
1706 edgeList->updateFaceNormals(egi->vertexSet, esrPositionBuffer);
1707 // If we're not extruding in software we still need to update
1708 // the latter part of the buffer (the hardware extruded part)
1709 // with the latest animated positions
1710 if (!extrude)
1712 // Lock, we'll be locking the (suppressed hardware update) shadow buffer
1713 float* pSrc = static_cast<float*>(
1714 esrPositionBuffer->lock(HardwareBuffer::HBL_NORMAL));
1715 float* pDest = pSrc + (egi->vertexData->vertexCount * 3);
1716 memcpy(pDest, pSrc, sizeof(float) * 3 * egi->vertexData->vertexCount);
1717 esrPositionBuffer->unlock();
1719 if (egi->vertexData == mMesh->sharedVertexData)
1721 updatedSharedGeomNormals = true;
1725 // Extrude vertices in software if required
1726 if (extrude)
1728 extrudeVertices(esrPositionBuffer,
1729 egi->vertexData->vertexCount,
1730 lightPos, extrusionDistance);
1733 // Stop suppressing hardware update now, if we were
1734 esrPositionBuffer->suppressHardwareUpdate(false);
1737 // Calc triangle light facing
1738 updateEdgeListLightFacing(edgeList, lightPos);
1740 // Generate indexes and update renderables
1741 generateShadowVolume(edgeList, *indexBuffer, light,
1742 mShadowRenderables, flags);
1745 return ShadowRenderableListIterator(mShadowRenderables.begin(), mShadowRenderables.end());
1747 //-----------------------------------------------------------------------
1748 const VertexData* Entity::findBlendedVertexData(const VertexData* orig)
1750 bool skel = hasSkeleton();
1752 if (orig == mMesh->sharedVertexData)
1754 return skel? mSkelAnimVertexData : mSoftwareVertexAnimVertexData;
1756 SubEntityList::iterator i, iend;
1757 iend = mSubEntityList.end();
1758 for (i = mSubEntityList.begin(); i != iend; ++i)
1760 SubEntity* se = *i;
1761 if (orig == se->getSubMesh()->vertexData)
1763 return skel? se->_getSkelAnimVertexData() : se->_getSoftwareVertexAnimVertexData();
1766 // None found
1767 OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
1768 "Cannot find blended version of the vertex data specified.",
1769 "Entity::findBlendedVertexData");
1771 //-----------------------------------------------------------------------
1772 SubEntity* Entity::findSubEntityForVertexData(const VertexData* orig)
1774 if (orig == mMesh->sharedVertexData)
1776 return 0;
1779 SubEntityList::iterator i, iend;
1780 iend = mSubEntityList.end();
1781 for (i = mSubEntityList.begin(); i != iend; ++i)
1783 SubEntity* se = *i;
1784 if (orig == se->getSubMesh()->vertexData)
1786 return se;
1790 // None found
1791 return 0;
1793 //-----------------------------------------------------------------------
1794 void Entity::addSoftwareAnimationRequest(bool normalsAlso)
1796 mSoftwareAnimationRequests++;
1797 if (normalsAlso) {
1798 mSoftwareAnimationNormalsRequests++;
1801 //-----------------------------------------------------------------------
1802 void Entity::removeSoftwareAnimationRequest(bool normalsAlso)
1804 if (mSoftwareAnimationRequests == 0 ||
1805 (normalsAlso && mSoftwareAnimationNormalsRequests == 0))
1807 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
1808 "Attempt to remove nonexistant request.",
1809 "Entity::removeSoftwareAnimationRequest");
1811 mSoftwareAnimationRequests--;
1812 if (normalsAlso) {
1813 mSoftwareAnimationNormalsRequests--;
1816 //-----------------------------------------------------------------------
1817 void Entity::_notifyAttached(Node* parent, bool isTagPoint)
1819 MovableObject::_notifyAttached(parent, isTagPoint);
1820 // Also notify LOD entities
1821 LODEntityList::iterator i, iend;
1822 iend = mLodEntityList.end();
1823 for (i = mLodEntityList.begin(); i != iend; ++i)
1825 (*i)->_notifyAttached(parent, isTagPoint);
1829 //-----------------------------------------------------------------------
1830 //-----------------------------------------------------------------------
1831 Entity::EntityShadowRenderable::EntityShadowRenderable(Entity* parent,
1832 HardwareIndexBufferSharedPtr* indexBuffer, const VertexData* vertexData,
1833 bool createSeparateLightCap, SubEntity* subent, bool isLightCap)
1834 : mParent(parent), mSubEntity(subent)
1836 // Save link to vertex data
1837 mCurrentVertexData = vertexData;
1839 // Initialise render op
1840 mRenderOp.indexData = OGRE_NEW IndexData();
1841 mRenderOp.indexData->indexBuffer = *indexBuffer;
1842 mRenderOp.indexData->indexStart = 0;
1843 // index start and count are sorted out later
1845 // Create vertex data which just references position component (and 2 component)
1846 mRenderOp.vertexData = OGRE_NEW VertexData();
1847 // Map in position data
1848 mRenderOp.vertexData->vertexDeclaration->addElement(0,0,VET_FLOAT3, VES_POSITION);
1849 mOriginalPosBufferBinding =
1850 vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION)->getSource();
1851 mPositionBuffer = vertexData->vertexBufferBinding->getBuffer(mOriginalPosBufferBinding);
1852 mRenderOp.vertexData->vertexBufferBinding->setBinding(0, mPositionBuffer);
1853 // Map in w-coord buffer (if present)
1854 if(!vertexData->hardwareShadowVolWBuffer.isNull())
1856 mRenderOp.vertexData->vertexDeclaration->addElement(1,0,VET_FLOAT1, VES_TEXTURE_COORDINATES, 0);
1857 mWBuffer = vertexData->hardwareShadowVolWBuffer;
1858 mRenderOp.vertexData->vertexBufferBinding->setBinding(1, mWBuffer);
1860 // Use same vertex start as input
1861 mRenderOp.vertexData->vertexStart = vertexData->vertexStart;
1863 if (isLightCap)
1865 // Use original vertex count, no extrusion
1866 mRenderOp.vertexData->vertexCount = vertexData->vertexCount;
1868 else
1870 // Vertex count must take into account the doubling of the buffer,
1871 // because second half of the buffer is the extruded copy
1872 mRenderOp.vertexData->vertexCount =
1873 vertexData->vertexCount * 2;
1874 if (createSeparateLightCap)
1876 // Create child light cap
1877 mLightCap = OGRE_NEW EntityShadowRenderable(parent,
1878 indexBuffer, vertexData, false, subent, true);
1883 //-----------------------------------------------------------------------
1884 Entity::EntityShadowRenderable::~EntityShadowRenderable()
1886 OGRE_DELETE mRenderOp.indexData;
1887 OGRE_DELETE mRenderOp.vertexData;
1889 //-----------------------------------------------------------------------
1890 void Entity::EntityShadowRenderable::getWorldTransforms(Matrix4* xform) const
1892 *xform = mParent->_getParentNodeFullTransform();
1894 //-----------------------------------------------------------------------
1895 void Entity::EntityShadowRenderable::rebindPositionBuffer(const VertexData* vertexData, bool force)
1897 if (force || mCurrentVertexData != vertexData)
1899 mCurrentVertexData = vertexData;
1900 mPositionBuffer = mCurrentVertexData->vertexBufferBinding->getBuffer(
1901 mOriginalPosBufferBinding);
1902 mRenderOp.vertexData->vertexBufferBinding->setBinding(0, mPositionBuffer);
1903 if (mLightCap)
1905 static_cast<EntityShadowRenderable*>(mLightCap)->rebindPositionBuffer(vertexData, force);
1909 //-----------------------------------------------------------------------
1910 bool Entity::EntityShadowRenderable::isVisible(void) const
1912 if (mSubEntity)
1914 return mSubEntity->isVisible();
1916 else
1918 return ShadowRenderable::isVisible();
1921 //-----------------------------------------------------------------------
1922 void Entity::setRenderQueueGroup(uint8 queueID)
1924 MovableObject::setRenderQueueGroup(queueID);
1926 // Set render queue for all manual LOD entities
1927 if (mMesh->isLodManual())
1929 LODEntityList::iterator li, liend;
1930 liend = mLodEntityList.end();
1931 for (li = mLodEntityList.begin(); li != liend; ++li)
1933 (*li)->setRenderQueueGroup(queueID);
1937 //-----------------------------------------------------------------------
1938 void Entity::shareSkeletonInstanceWith(Entity* entity)
1940 if (entity->getMesh()->getSkeleton() != getMesh()->getSkeleton())
1942 OGRE_EXCEPT(Exception::ERR_RT_ASSERTION_FAILED,
1943 "The supplied entity has a different skeleton.",
1944 "Entity::shareSkeletonWith");
1946 if (!mSkeletonInstance)
1948 OGRE_EXCEPT(Exception::ERR_RT_ASSERTION_FAILED,
1949 "This entity has no skeleton.",
1950 "Entity::shareSkeletonWith");
1952 if (mSharedSkeletonEntities != NULL && entity->mSharedSkeletonEntities != NULL)
1954 OGRE_EXCEPT(Exception::ERR_RT_ASSERTION_FAILED,
1955 "Both entities already shares their SkeletonInstances! At least "
1956 "one of the instances must not share it's instance.",
1957 "Entity::shareSkeletonWith");
1960 //check if we already share our skeletoninstance, we don't want to delete it if so
1961 if (mSharedSkeletonEntities != NULL)
1963 entity->shareSkeletonInstanceWith(this);
1965 else
1967 OGRE_DELETE mSkeletonInstance;
1968 OGRE_FREE_SIMD(mBoneMatrices, MEMCATEGORY_ANIMATION);
1969 OGRE_DELETE mAnimationState;
1970 // using OGRE_FREE since unsigned long is not a destructor
1971 OGRE_FREE(mFrameBonesLastUpdated, MEMCATEGORY_ANIMATION);
1972 mSkeletonInstance = entity->mSkeletonInstance;
1973 mNumBoneMatrices = entity->mNumBoneMatrices;
1974 mBoneMatrices = entity->mBoneMatrices;
1975 mAnimationState = entity->mAnimationState;
1976 mFrameBonesLastUpdated = entity->mFrameBonesLastUpdated;
1977 if (entity->mSharedSkeletonEntities == NULL)
1979 entity->mSharedSkeletonEntities = OGRE_NEW_T(EntitySet, MEMCATEGORY_ANIMATION)();
1980 entity->mSharedSkeletonEntities->insert(entity);
1982 mSharedSkeletonEntities = entity->mSharedSkeletonEntities;
1983 mSharedSkeletonEntities->insert(this);
1986 //-----------------------------------------------------------------------
1987 void Entity::stopSharingSkeletonInstance()
1989 if (mSharedSkeletonEntities == NULL)
1991 OGRE_EXCEPT(Exception::ERR_RT_ASSERTION_FAILED,
1992 "This entity is not sharing it's skeletoninstance.",
1993 "Entity::shareSkeletonWith");
1995 //check if there's no other than us sharing the skeleton instance
1996 if (mSharedSkeletonEntities->size() == 1)
1998 //just reset
1999 OGRE_DELETE_T(mSharedSkeletonEntities, EntitySet, MEMCATEGORY_ANIMATION);
2000 mSharedSkeletonEntities = 0;
2002 else
2004 mSkeletonInstance = OGRE_NEW SkeletonInstance(mMesh->getSkeleton());
2005 mSkeletonInstance->load();
2006 mAnimationState = OGRE_NEW AnimationStateSet();
2007 mMesh->_initAnimationState(mAnimationState);
2008 mFrameBonesLastUpdated = OGRE_NEW_T(unsigned long, MEMCATEGORY_ANIMATION)(std::numeric_limits<unsigned long>::max());
2009 mNumBoneMatrices = mSkeletonInstance->getNumBones();
2010 mBoneMatrices = static_cast<Matrix4*>(OGRE_MALLOC_SIMD(sizeof(Matrix4) * mNumBoneMatrices, MEMCATEGORY_ANIMATION));
2012 mSharedSkeletonEntities->erase(this);
2013 if (mSharedSkeletonEntities->size() == 1)
2015 (*mSharedSkeletonEntities->begin())->stopSharingSkeletonInstance();
2017 mSharedSkeletonEntities = 0;
2020 //-----------------------------------------------------------------------
2021 void Entity::refreshAvailableAnimationState(void)
2023 mMesh->_refreshAnimationState(mAnimationState);
2025 //-----------------------------------------------------------------------
2026 uint32 Entity::getTypeFlags(void) const
2028 return SceneManager::ENTITY_TYPE_MASK;
2030 //-----------------------------------------------------------------------
2031 VertexData* Entity::getVertexDataForBinding(void)
2033 Entity::VertexDataBindChoice c =
2034 chooseVertexDataForBinding(mMesh->getSharedVertexDataAnimationType() != VAT_NONE);
2035 switch(c)
2037 case BIND_ORIGINAL:
2038 return mMesh->sharedVertexData;
2039 case BIND_HARDWARE_MORPH:
2040 return mHardwareVertexAnimVertexData;
2041 case BIND_SOFTWARE_MORPH:
2042 return mSoftwareVertexAnimVertexData;
2043 case BIND_SOFTWARE_SKELETAL:
2044 return mSkelAnimVertexData;
2046 // keep compiler happy
2047 return mMesh->sharedVertexData;
2049 //-----------------------------------------------------------------------
2050 Entity::VertexDataBindChoice Entity::chooseVertexDataForBinding(bool vertexAnim) const
2052 if (hasSkeleton())
2054 if (!mHardwareAnimation)
2056 // all software skeletal binds same vertex data
2057 // may be a 2-stage s/w transform including morph earlier though
2058 return BIND_SOFTWARE_SKELETAL;
2060 else if (vertexAnim)
2062 // hardware morph animation
2063 return BIND_HARDWARE_MORPH;
2065 else
2067 // hardware skeletal, no morphing
2068 return BIND_ORIGINAL;
2071 else if (vertexAnim)
2073 // morph only, no skeletal
2074 if (mHardwareAnimation)
2076 return BIND_HARDWARE_MORPH;
2078 else
2080 return BIND_SOFTWARE_MORPH;
2084 else
2086 return BIND_ORIGINAL;
2090 //---------------------------------------------------------------------
2091 void Entity::visitRenderables(Renderable::Visitor* visitor,
2092 bool debugRenderables)
2094 // Visit each SubEntity
2095 for (SubEntityList::iterator i = mSubEntityList.begin(); i != mSubEntityList.end(); ++i)
2097 visitor->visit(*i, 0, false);
2099 // if manual LOD is in use, visit those too
2100 ushort lodi = 1;
2101 for (LODEntityList::iterator e = mLodEntityList.begin();
2102 e != mLodEntityList.end(); ++e, ++lodi)
2105 uint nsub = (*e)->getNumSubEntities();
2106 for (uint s = 0; s < nsub; ++s)
2108 visitor->visit((*e)->getSubEntity(s), lodi, false);
2113 //-----------------------------------------------------------------------
2114 //-----------------------------------------------------------------------
2115 String EntityFactory::FACTORY_TYPE_NAME = "Entity";
2116 //-----------------------------------------------------------------------
2117 const String& EntityFactory::getType(void) const
2119 return FACTORY_TYPE_NAME;
2121 //-----------------------------------------------------------------------
2122 MovableObject* EntityFactory::createInstanceImpl( const String& name,
2123 const NameValuePairList* params)
2125 // must have mesh parameter
2126 MeshPtr pMesh;
2127 if (params != 0)
2129 String groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME;
2131 NameValuePairList::const_iterator ni;
2133 ni = params->find("resourceGroup");
2134 if (ni != params->end())
2136 groupName = ni->second;
2139 ni = params->find("mesh");
2140 if (ni != params->end())
2142 // Get mesh (load if required)
2143 pMesh = MeshManager::getSingleton().load(
2144 ni->second,
2145 // autodetect group location
2146 groupName );
2150 if (pMesh.isNull())
2152 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
2153 "'mesh' parameter required when constructing an Entity.",
2154 "EntityFactory::createInstance");
2157 return OGRE_NEW Entity(name, pMesh);
2160 //-----------------------------------------------------------------------
2161 void EntityFactory::destroyInstance( MovableObject* obj)
2163 OGRE_DELETE obj;