//----------------------------------------------------------------------- size_t InstancedEntity::getTransforms( Matrix4 *xform ) const { size_t retVal = 1; //When not attached, returns zero matrix to avoid rendering this one, not identity if( isVisible() && isInScene() ) { if( !mSkeletonInstance ) { *xform = mBatchOwner->useBoneWorldMatrices() ? _getParentNodeFullTransform() : Matrix4::IDENTITY; } else { Matrix4* matrices = mBatchOwner->useBoneWorldMatrices() ? mBoneWorldMatrices : mBoneMatrices; const Mesh::IndexMap *indexMap = mBatchOwner->_getIndexToBoneMap(); Mesh::IndexMap::const_iterator itor = indexMap->begin(); Mesh::IndexMap::const_iterator end = indexMap->end(); while( itor != end ) *xform++ = matrices[*itor++]; retVal = indexMap->size(); } } else { if( mSkeletonInstance ) retVal = mBatchOwner->_getIndexToBoneMap()->size(); std::fill_n( xform, retVal, Matrix4::ZEROAFFINE ); } return retVal; }
//----------------------------------------------------------------------- const AxisAlignedBox& MovableObject::getWorldBoundingBox(bool derive) const { if (derive) { mWorldAABB = this->getBoundingBox(); mWorldAABB.transformAffine(_getParentNodeFullTransform()); } return mWorldAABB; }
//----------------------------------------------------------------------- void PrimitiveShapeSet::getWorldTransforms(Ogre::Matrix4* xform) const { if (mWorldSpace) { *xform = Ogre::Matrix4::IDENTITY; } else { *xform = _getParentNodeFullTransform(); } }
//----------------------------------------------------------------------- size_t InstancedEntity::getTransforms3x4( float *xform ) const { size_t retVal; //When not attached, returns zero matrix to avoid rendering this one, not identity if( isVisible() && isInScene() ) { if( !mSkeletonInstance ) { const Matrix4& mat = mBatchOwner->useBoneWorldMatrices() ? _getParentNodeFullTransform() : Matrix4::IDENTITY; for( int i=0; i<3; ++i ) { Real const *row = mat[i]; for( int j=0; j<4; ++j ) *xform++ = static_cast<float>( *row++ ); } retVal = 12; } else { Matrix4* matrices = mBatchOwner->useBoneWorldMatrices() ? mBoneWorldMatrices : mBoneMatrices; const Mesh::IndexMap *indexMap = mBatchOwner->_getIndexToBoneMap(); Mesh::IndexMap::const_iterator itor = indexMap->begin(); Mesh::IndexMap::const_iterator end = indexMap->end(); while( itor != end ) { const Matrix4 &mat = matrices[*itor++]; for( int i=0; i<3; ++i ) { Real const *row = mat[i]; for( int j=0; j<4; ++j ) *xform++ = static_cast<float>( *row++ ); } } retVal = indexMap->size() * 4 * 3; } } else { if( mSkeletonInstance ) retVal = mBatchOwner->_getIndexToBoneMap()->size() * 3 * 4; else retVal = 12; std::fill_n( xform, retVal, 0.0f ); } return retVal; }
//----------------------------------------------------------------------- void Entity::cacheBoneMatrices(void) { // Get the appropriate meshes skeleton here // Can use lower LOD mesh skeleton if mesh LOD is manual // We make the assumption that lower LOD meshes will have // fewer bones than the full LOD, therefore marix stack will be // big enough. Mesh* theMesh; if (mMesh->isLodManual() && mMeshLodIndex > 1) { // Use lower detail skeleton theMesh = mMesh->getLodLevel(mMeshLodIndex).manualMesh; // Lower detail may not have skeleton if (!theMesh->hasSkeleton()) { mNumBoneMatrices = 0; return; } } else { // Use normal mesh theMesh = mMesh; } // Tell the skeleton who's making a call to update him theMesh->getSkeleton()->setCurrentEntity(this); theMesh->_getBoneMatrices(mAnimationState, mBoneMatrices); // Reset the skeleton to 'no caller' theMesh->getSkeleton()->setCurrentEntity(0); // Apply our current world transform to these too, since these are used as // replacement world matrices int i; Matrix4 worldXform = _getParentNodeFullTransform(); mNumBoneMatrices = theMesh->_getNumBoneMatrices(); for (i = 0; i < mNumBoneMatrices; ++i) { mBoneMatrices[i] = worldXform * mBoneMatrices[i]; } }
//----------------------------------------------------------------------- bool InstancedEntity::_updateAnimation(void) { if (mSharedTransformEntity) { return mSharedTransformEntity->_updateAnimation(); } else { const bool animationDirty = (mFrameAnimationLastUpdated != mAnimationState->getDirtyFrameNumber()) || (mSkeletonInstance->getManualBonesDirty()); if( animationDirty || (mNeedAnimTransformUpdate && mBatchOwner->useBoneWorldMatrices())) { mSkeletonInstance->setAnimationState( *mAnimationState ); mSkeletonInstance->_getBoneMatrices( mBoneMatrices ); // Cache last parent transform for next frame use too. if (mBatchOwner->useBoneWorldMatrices()) { OptimisedUtil::getImplementation()->concatenateAffineMatrices( _getParentNodeFullTransform(), mBoneMatrices, mBoneWorldMatrices, mSkeletonInstance->getNumBones() ); mNeedAnimTransformUpdate = false; } mFrameAnimationLastUpdated = mAnimationState->getDirtyFrameNumber(); return true; } } return false; }
//----------------------------------------------------------------------- void BillboardChain::getWorldTransforms(Matrix4* xform) const { *xform = _getParentNodeFullTransform(); }