Entity 的定位:在ogre里面Entity和诸多类似Entity的类一样,它们是场景中资源的实际掌控者。主要包括有网格,骨骼动画,以及对lod的维护。
1.资源加载:
void Entity::_initialise(bool forceReinitialise)
{
if (forceReinitialise)
_deinitialise(); // 如果为强制重新加载,会调用此方法对已有的资源进行释放
if (mInitialised)
return;
if (mMesh->isBackgroundLoaded() && !mMesh->isLoaded())
{
// register for a callback when mesh is finished loading
// do this before asking for load to happen to avoid race
mMesh->addListener(this);
}
// On-demand load
mMesh->load(); // 网格加载
// If loading failed, or deferred loading isn't done yet, defer
// Will get a callback in the case of deferred loading
// Skeletons are cascade-loaded so no issues there
if (!mMesh->isLoaded())
return;
// Is mesh skeletally animated?
if (mMesh->hasSkeleton() && !mMesh->getSkeleton().isNull())
{
mSkeletonInstance = OGRE_NEW SkeletonInstance(mMesh->getSkeleton());
mSkeletonInstance->load(); //如果拥有骨骼动画,加载骨骼动画
}
// Build main subentity list
buildSubEntityList(mMesh, &mSubEntityList); //构建SubEntity,众所周知SubEntity才是真正可以渲染的对象
// Check if mesh is using manual LOD
if (mMesh->isLodManual())
{
ushort i, numLod;
numLod = mMesh->getNumLodLevels();
// NB skip LOD 0 which is the original
for (i = 1; i < numLod; ++i)
{
const MeshLodUsage& usage = mMesh->getLodLevel(i);
// Manually create entity
Entity* lodEnt = OGRE_NEW Entity(mName + "Lod" + StringConverter::toString(i),
usage.manualMesh);
mLodEntityList.push_back(lodEnt);
}
}
// Initialise the AnimationState, if Mesh has animation
if (hasSkeleton())
{
mFrameBonesLastUpdated = OGRE_NEW_T(unsigned long, MEMCATEGORY_ANIMATION)(std::numeric_limits<unsigned long>::max());
mNumBoneMatrices = mSkeletonInstance->getNumBones();
mBoneMatrices = static_cast<Matrix4*>(OGRE_MALLOC_SIMD(sizeof(Matrix4) * mNumBoneMatrices, MEMCATEGORY_ANIMATION));
}
if (hasSkeleton() || hasVertexAnimation())
{
mAnimationState = OGRE_NEW AnimationStateSet();
mMesh->_initAnimationState(mAnimationState);
prepareTempBlendBuffers();
}
reevaluateVertexProcessing();
// Update of bounds of the parent SceneNode, if Entity already attached
// this can happen if Mesh is loaded in background or after reinitialisation
if( mParentNode )
{
getParentSceneNode()->needUpdate();
}
mInitialised = true;
mMeshStateCount = mMesh->getStateCount();
}