void VoodooEntityView::OnEntityAttributeChanged( Entity* Rhs, const std::string& Name, const EntityVariantType* Attribute ) { if ( Name == "Position" ) { // Set the position, if it is available const vec3* Data = boost::get<vec3>( Attribute ); if ( Data ) mNode->setPosition( *Data ); } else if( Name == "Scale" ) { // Set the scale, if it is available const vec3* Data = boost::get<vec3>( Attribute ); if( Data ) mNode->setScale( *Data ); } else if ( Name == "Model" ) { // Delete all old bone names if ( mOgreEntity ) { typedef Ogre::SkeletonInstance::BoneIterator iterator; Ogre::SkeletonInstance* Skeleton= mOgreEntity->getSkeleton(); for ( iterator i=Skeleton->getBoneIterator(); i.hasMoreElements(); ) { Ogre::Bone* Bone=i.getNext(); GetDataEntity()->RemoveAttribute( Bone->getName()); } mNode->detachObject( mOgreEntity ); GetSceneManager()->destroyEntity( mOgreEntity ); mOgreEntity=0; } const std::string* Data=boost::get<std::string>( Attribute ); if (!Data) return; // Create and attach the model entity const std::string EntityName = "Entity:" + boost::lexical_cast<std::string>( GetDataEntity() ); mOgreEntity = GetSceneManager()->createEntity( EntityName, *Data ); mNode->attachObject( mOgreEntity ); // Get all bones as properties typedef Ogre::SkeletonInstance::BoneIterator iterator; Ogre::SkeletonInstance* Skeleton=mOgreEntity->getSkeleton(); Skeleton->setBindingPose(); for ( iterator i=Skeleton->getBoneIterator(); i.hasMoreElements(); ) { Ogre::Bone* Bone=i.getNext(); Bone->setManuallyControlled( true ); const std::string Name=Bone->getName(); const quat Val = Bone->getOrientation(); // if this attribute has already a attribute, do not overwrite it and inform observers (to get visualize the orientation here) if ( GetDataEntity()->GetAttribute( Name ) == 0 ) { GetDataEntity()->Set<quat>( Name, Val ); } else { GetDataEntity()->Changed( Name, GetDataEntity()->GetAttribute( Name )); } } } else if (Rhs->GetAttribute( "Model" ) != 0) { const Entity::AttributeType& Attributes=Rhs->GetAttributes(); typedef Entity::AttributeType::value_type ValueType; // Check if this is an angle value and a bone of this name exists Ogre::SkeletonInstance* Skeleton=mOgreEntity->getSkeleton(); const quat* Val = boost::get<quat>( Attribute ); if ( Val && Skeleton->hasBone( Name ) ) { Ogre::Bone* Bone=Skeleton->getBone( Name ); Ogre::Quaternion CorrectorX; CorrectorX.FromAngleAxis( Ogre::Radian( Ogre::Degree( - 90 ) ), vec3( 1.f, 0.f, 0.f ) ); Ogre::Quaternion CorrectorZ; CorrectorZ.FromAngleAxis( Ogre::Radian( Ogre::Degree( 90 ) ), vec3( 0.f, 0.f, 1.f ) ); Ogre::Quaternion Corrector = CorrectorX * CorrectorZ; Bone->setOrientation( Bone->getInitialOrientation() * Corrector * ( *Val ) * Corrector.UnitInverse() ); // FIXME: is this really needed? mOgreEntity->getAllAnimationStates()->_notifyDirty(); } } }