void OgreApplication::SetupAnimation(Ogre::String object_name){

	/* Retrieve scene manager and root scene node */
    Ogre::SceneManager* scene_manager = ogre_root_->getSceneManager("MySceneManager");
	Ogre::SceneNode* root_scene_node = scene_manager->getRootSceneNode();

	/* Set up animation */
	Ogre::Real duration = Ogre::Math::TWO_PI;
	Ogre::Real num_steps = 36;
	Ogre::Real step = duration/num_steps;
	Ogre::Animation* animation = scene_manager->createAnimation("Animation", duration);
	animation->setInterpolationMode(Ogre::Animation::IM_LINEAR);
	Ogre::Node *object_scene_node = root_scene_node->getChild(object_name);
	Ogre::NodeAnimationTrack* track = animation->createNodeTrack(0, object_scene_node);

	/* Set up frames for animation */
	Ogre::TransformKeyFrame* key;
	Ogre::Quaternion quat;
	for (int i = 0; i < num_steps; i++){
		Ogre::Real current = ((float) i) * step;
		key = track->createNodeKeyFrame(current);
		quat.FromAngleAxis(Ogre::Radian(-current), Ogre::Vector3(0, 1, 0));
		key->setRotation(quat);
		key->setScale(Ogre::Vector3(0.5, 0.5, 0.5));
	}

	/* Create animation state */
	animation_state_ = scene_manager->createAnimationState("Animation");
	animation_state_->setEnabled(true);
	animation_state_->setLoop(true);

	/* Turn on animating flag */
	animating_ = true;
}
void ActorAnimationSettingEditor::init()
{

	wxGraphDialog* pGraphDialog = m_Frame->GetGraphDialog();
	if(pGraphDialog)
		pGraphDialog->SetLoop(mDObject->getAnimationLoop());

	this->SetTitle(Fairy::VariantCast<Ogre::String>(mObject->getProperty("actor name")));

	//重新设置动画列表框

	mListBoxAnimation->Clear();

	for ( unsigned short i = 0; i < mDObject->getSkeletonAnimationCount(); ++i )
	{
		Ogre::Animation *anim = mDObject->getSkeletonAnimation(i);

		if ( anim )
		{
			wxString nameStr(anim->getName().c_str());
			mListBoxAnimation->InsertItems( 1, &nameStr, 0 );            
		}
	}
	// 加入obj中定义的动作名称
	Fairy::LogicModelManager::AnimationSkeletonLinksIterator asmIt = 
		Fairy::LogicModelManager::getSingleton().getAnimationSkeletonLinksIterator(mDObject->getName());

	while ( asmIt.hasMoreElements() )
	{
		wxString animName(asmIt.peekNextKey().c_str());

		if ( wxNOT_FOUND == mListBoxAnimation->FindString(animName) )
		{
			wxString nameStr(animName.c_str());
			mListBoxAnimation->InsertItems( 1, &nameStr, 0 );
		}

		asmIt.moveNext();
	}

	//重新设置声音
	if ( NULL == Fairy::LogicModel::GetPlaySoundFuncton() )
	{
		Fairy::LogicModel::SetPlaySoundFuncton(wxGetApp().funcPlay);
	}

	if ( NULL == Fairy::LogicModel::GetStopSoundFunction() )
		Fairy::LogicModel::SetStopSoundFunction(wxGetApp().funcStop);


   
}
void AssetLoader::createCamera(Ogre::SceneManager* sceneMgr, const aiScene* scene, Ogre::String camName)
{
	for (size_t n = 0; n < scene->mNumCameras; n++)
	{
		// カメラを作成
		Ogre::Camera* cam = sceneMgr->createCamera(scene->mCameras[n]->mName.data);
		std::cout << "Create Camra " << cam->getName() << " " << scene->mCameras[n]->mHorizontalFOV << std::endl;
		cam->setFOVy(Ogre::Radian(scene->mCameras[n]->mHorizontalFOV));
		
		// 視点アニメーション用ノード
		Ogre::SceneNode* camNode = sceneMgr->getRootSceneNode()->createChildSceneNode(cam->getName()+"CamNode");
		camNode->attachObject(cam);

		// アニメーションを走査
		for (size_t na = 0; na < scene->mNumAnimations; na++) {
			aiAnimation* aiani = scene->mAnimations[na];
			for (size_t nc = 0; nc < aiani->mNumChannels; nc++) {
				// カメラと同じ名前のチャネルを取得する
				if (Ogre::String(scene->mCameras[n]->mName.data) == cam->getName()) {
					
					//アニメーションを付けるトラックを作成しておく
					Ogre::Animation* ogani = sceneMgr->createAnimation(cam->getName()+"Animation", aiani->mDuration);
					std::cout << "Animation : " << ogani->getName() << std::endl; 
					Ogre::NodeAnimationTrack* track = ogani->createNodeTrack(0, camNode);
					ogani->setInterpolationMode(Ogre::Animation::IM_LINEAR);

					// アニメーションチャネルからキーフレームアニメーションを取得
					aiNodeAnim* chan = aiani->mChannels[n];
					for (size_t np = 0; np < chan->mNumPositionKeys; np++) {						
						aiVectorKey* vk = &(chan->mPositionKeys[np]);
						Ogre::TransformKeyFrame* key = track->createNodeKeyFrame(vk->mTime);
						key->setTranslate(Ogre::Vector3(vk->mValue[0], vk->mValue[1], vk->mValue[2]));

						aiQuatKey* qk = &(chan->mRotationKeys[np]);
						key->setRotation(Ogre::Quaternion(qk->mValue.w, qk->mValue.x, qk->mValue.y, qk->mValue.z));
					}

					// 管理するアニメーションの名前を付けておく
					Ogre::AnimationState* aniState = sceneMgr->createAnimationState(ogani->getName());
					aniState->setEnabled(true);
					aniState->setLoop(true);
					aniState->setTimePosition(0.0);

					//ループを抜ける
					na = scene->mNumAnimations;
					break;
				}
			}
		}
	}
}
Beispiel #4
0
void CMonster3D::setupSkeleton(std::string skeletonFile)
{
   Ogre::SkeletonPtr pSkeletonBody = Ogre::SkeletonManager::getSingleton().getByName(m_meshName + ".skeleton");

   Ogre::Skeleton::BoneHandleMap boneHandleMap;
  
   Ogre::SkeletonPtr pNewSkeleton = Ogre::SkeletonManager::getSingleton().load(skeletonFile, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
   Ogre::Animation *pSrcAnimation = pNewSkeleton->getAnimation(0);
   std::string newAnimationName = pSrcAnimation->getName() + "::" + m_pMonsterNode->getName();
   Ogre::Animation *pNewAnimation = pNewSkeleton->createAnimation(newAnimationName, pSrcAnimation->getLength());
   Ogre::Animation *pCloneAnimation = pNewSkeleton->getAnimation(0)->clone(newAnimationName);
   *pNewAnimation = *pCloneAnimation;
   pNewSkeleton->removeAnimation(pSrcAnimation->getName());

   pNewSkeleton->_buildMapBoneByHandle(pNewSkeleton.getPointer(), boneHandleMap);
   pSkeletonBody->_mergeSkeletonAnimations(pNewSkeleton.getPointer(), boneHandleMap);
   Ogre::SkeletonManager::getSingleton().remove(skeletonFile);

   m_pBodyEntity->getSkeleton()->_refreshAnimationState(m_pBodyEntity->getAllAnimationStates());
}
Beispiel #5
0
void MenuScene::createAnimation(void)
{

	Ogre::SceneNode *titleNode = static_cast<Ogre::SceneNode *>(mSceneMgr->getRootSceneNode()->getChild("boomb_title"));
	Ogre::Animation *anim = mSceneMgr->createAnimation("title_animation", 3);
	anim->setInterpolationMode(Ogre::Animation::IM_SPLINE);
	Ogre::NodeAnimationTrack *track = anim->createNodeTrack(0, titleNode);
	Ogre::TransformKeyFrame *key = track->createNodeKeyFrame(0);
	key->setTranslate(Ogre::Vector3(0,0,100));
	Ogre::Quaternion q1 = titleNode->getOrientation();
	Ogre::Quaternion q2(Ogre::Degree(45), Ogre::Vector3::UNIT_X);
	key->setRotation(q2);
	key = track->createNodeKeyFrame(1.5);
	key->setTranslate(Ogre::Vector3(0,0,120));
	key->setRotation(q2);
	key = track->createNodeKeyFrame(3);
	key->setTranslate(Ogre::Vector3(0,0,100));
	key->setRotation(q2);

	mTitleAnimState = mSceneMgr->createAnimationState("title_animation");
	mTitleAnimState->setEnabled(true);
	mTitleAnimState->setLoop(true);

	Ogre::SceneNode *backgroundNode = static_cast<Ogre::SceneNode *>(mSceneMgr->getRootSceneNode()->getChild("boomb_background"));
	anim = mSceneMgr->createAnimation("background_animation", 30);
	anim->setInterpolationMode(Ogre::Animation::IM_SPLINE);
	track = anim->createNodeTrack(0, backgroundNode);
	key = track->createNodeKeyFrame(0);
	key->setTranslate(Ogre::Vector3(20,0,20));
	key = track->createNodeKeyFrame(15);
	key->setTranslate(Ogre::Vector3(-20,0,-20));
	key = track->createNodeKeyFrame(30);
	key->setTranslate(Ogre::Vector3(20,0,20));
	mBackgroundAnimState = mSceneMgr->createAnimationState("background_animation");
	mBackgroundAnimState->setEnabled(true);
	mBackgroundAnimState->setLoop(true);
}
wxPGConstants * FairySkillEditDialog::PopulateConstants(const Ogre::String& name)
{
	size_t id = reinterpret_cast<size_t>(&name);
	wxPGConstants* constants = wxPropertyGrid::GetConstantsArray(id);

	if (constants)
	{
		for (std::list<wxPGConstants*>::iterator it = mConstantList.begin(); it != mConstantList.end(); ++it)
		{
			if (constants == *it)
			{
				if (constants->UnRef())
					delete constants;

				mConstantList.erase(it);

				break;
			}
		}
	}

//	if (!constants)
//	{
		constants = wxPropertyGrid::CreateConstantsArray(id);

		if ( name == "Animation" )
		{
			// 第一个为空,表示设置这个元素的材质是用原mesh的材质
			for ( unsigned short i = 0; i < mDObject->getSkeletonAnimationCount(); ++i )
			{
				Ogre::Animation *anim = mDObject->getSkeletonAnimation(i);

				if ( anim )
				{
					constants->Add(anim->getName().c_str());
				}
			}			
		}
		else if ( name == "EffectTemplateName" )
		{
			WX::EffectManager::EffectTemplateIterator it = 
				WX::EffectManager::getSingleton().getEffectTemplateIterator();

			while ( it.hasMoreElements() )
			{
				constants->Add(it.peekNextKey().c_str());

				it.moveNext();
			}
		}
		else if ( name == "AttachPoint" )
		{
			for ( unsigned short i=0; i<mDObject->getNumBones(); ++i )
			{
				constants->Add(mDObject->getBoneName(i).c_str());
			}	

			Ogre::StringVector locatorNames;
			mDObject->getLocatorNames(locatorNames);

			for ( size_t i=0; i<locatorNames.size(); ++i )
			{
				constants->Add(locatorNames[i].c_str());
			}			
		}
		else if ( name == "Material" )
		{
			typedef std::list<Ogre::String> MaterialFileNameList;
			MaterialFileNameList materialFileNameList;

			Ogre::FileInfoListPtr fileInfoList =
				Ogre::ResourceGroupManager::getSingleton().findResourceFileInfo(
				Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
				"*.material");
			for (Ogre::FileInfoList::const_iterator it = fileInfoList->begin(); it != fileInfoList->end(); ++it)
			{
				if ( it->archive->getName() == MATERIAL_PATH)
				{
					materialFileNameList.push_back(it->filename);
				}
			}

			Ogre::ResourceManager::ResourceMapIterator resourceMapIterator = Ogre::MaterialManager::getSingleton().getResourceIterator();

			while ( resourceMapIterator.hasMoreElements() )
			{				
				Ogre::String matName = resourceMapIterator.peekNextValue()->getName();

				for ( MaterialFileNameList::iterator i = materialFileNameList.begin();
					i != materialFileNameList.end(); ++i )
				{
					if ( *i == resourceMapIterator.peekNextValue()->getOrigin() )
					{
						constants->Add(matName.c_str());
						break;
					}
				}

				resourceMapIterator.moveNext();
			}
		}	
		else if ( name == "SoundName" )
		{
            constants->Add("NULL");
			//-----------------------------------
			//得到所有文件名
            if (wxGetApp().funcEnumSoundFile)
            {
			    int nIndex = 0;
			    do
			    {
				    char szTemp[100];

                    int id;

				    bool bHave = wxGetApp().funcEnumSoundFile(nIndex++, szTemp, 100, id);
				    if(!bHave) break;

				    constants->Add(szTemp);
			    }while(true);
            }
		}

		registerConstants(constants);
	//}

	return constants;
}
void
AddSkillDialog::OnInitDialog(wxInitDialogEvent &e)
{
	wxDialog::OnInitDialog(e);

	wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );

	wxFlexGridSizer *item1 = new wxFlexGridSizer( 2, 0, 0 );

	wxStaticText *item2 = new wxStaticText( this, ID_TEXT, /*_("Animation")*/ wxT("动作"), wxDefaultPosition, wxDefaultSize, 0 );
	item1->Add( item2, 0, wxALIGN_CENTER|wxALL, 5 );

	wxString *strs3 = (wxString*) NULL;
	wxComboBox *item3 = new wxComboBox( this, ID_COMBO_ANIMATION, wxT(""), wxDefaultPosition, wxSize(200,-1), 0, strs3, wxCB_DROPDOWN );
	item1->Add( item3, 0, wxALIGN_CENTER|wxALL, 5 );

	wxStaticText *item4 = new wxStaticText( this, ID_TEXT, /*_("Skill Name")*/wxT("技能名称"), wxDefaultPosition, wxDefaultSize, 0 );
	item1->Add( item4, 0, wxALIGN_CENTER|wxALL, 5 );

	wxTextCtrl *item5 = new wxTextCtrl( this, ID_TEXTCTRL_SKILL, wxT(""), wxDefaultPosition, wxSize(200,-1), 0 );
	item1->Add( item5, 0, wxALIGN_CENTER|wxALL, 5 );

	wxButton *item6 = new wxButton( this, wxID_OK, /*_("OK")*/wxT("确认[&O]"), wxDefaultPosition, wxDefaultSize, 0 );
	item1->Add( item6, 0, wxALIGN_CENTER|wxALL, 5 );

	wxButton *item7 = new wxButton( this, wxID_CANCEL, /*_("Cancel")*/wxT("取消[&C]"), wxDefaultPosition, wxDefaultSize, 0 );
	item1->Add( item7, 0, wxALIGN_CENTER|wxALL, 5 );

	item0->Add( item1, 0, wxALIGN_CENTER|wxALL, 5 );

	this->SetSizer( item0 );
	item0->SetSizeHints( this );

	ActorAnimationSettingDialog *parentDialog = static_cast<ActorAnimationSettingDialog *>(this->GetParent());
	assert (parentDialog);
	WX::LogicModel *object = parentDialog->GetCurrentObject();
	
	for ( unsigned short i = 0; i < object->getSkeletonAnimationCount(); ++i )
	{
		Ogre::Animation *anim = object->getSkeletonAnimation(i);

		if ( anim )
		{
			wxString nameStr(anim->getName().c_str());
			item3->AppendString(nameStr);
		}
	}

    // 加入obj中定义的动作名称
    WX::LogicModelManager::AnimationSkeletonLinksIterator asmIt = 
        WX::LogicModelManager::getSingleton().getAnimationSkeletonLinksIterator(object->getName());

    while ( asmIt.hasMoreElements() )
    {
        wxString animName(asmIt.peekNextKey().c_str());

        if ( wxNOT_FOUND == item3->FindString(animName) )
        {
            wxString nameStr(animName.c_str());
            item3->AppendString(nameStr);
        }

        asmIt.moveNext();
    }

	item3->SetSelection(0);
	mAnimComboBox = item3;

	mSkillNameTextCtrl = item5;	
}
void ActorAnimationSettingDialog::OnInitDialog(wxInitDialogEvent &e)
{
	wxDialog::OnInitDialog(e);
	wxSizer* sizer = ActorAnimationSetting(this, true, true);

	// 获取各控件的引用
	mListBoxAnimation = wxDynamicCast(this->FindWindow(ID_LISTBOX_ANIMATION),wxListBox);
	mSliderAnimTimePos = wxDynamicCast(this->FindWindow(ID_SLIDER_TIME),wxSlider);
	mSliderAnimRate = wxDynamicCast(this->FindWindow(ID_SLIDER_GLOBAL_ANIM_RATE),wxSlider);
	mSliderAnimFadeOutTime = wxDynamicCast(this->FindWindow(ID_SLIDER_FADE_OUT_TIME),wxSlider);

	mListBoxAllSkill = wxDynamicCast(this->FindWindow(ID_LISTBOX_ALL_SKILL),wxListBox);
	mCheckBoxLoop = wxDynamicCast(this->FindWindow(ID_CHECKBOX_LOOP),wxCheckBox);

	mHairTextCtrl = wxDynamicCast(this->FindWindow(ID_TEXTCTRL_HAIR), wxTextCtrl);
	mCapTextCtrl = wxDynamicCast(this->FindWindow(ID_TEXTCTRL_CAP), wxTextCtrl);
	mBodyTextCtrl = wxDynamicCast(this->FindWindow(ID_TEXTCTRL_BODY), wxTextCtrl);
	mHandTextCtrl = wxDynamicCast(this->FindWindow(ID_TEXTCTRL_HAND), wxTextCtrl);
	mFootTextCtrl = wxDynamicCast(this->FindWindow(ID_TEXTCTRL_FOOT), wxTextCtrl);

    mHairTextMatCtrl = wxDynamicCast(this->FindWindow(ID_TEXTCTRL_HAIR_MAT), wxTextCtrl);
    mCapTextMatCtrl = wxDynamicCast(this->FindWindow(ID_TEXTCTRL_CAP_MAT), wxTextCtrl);
    mBodyTextMatCtrl = wxDynamicCast(this->FindWindow(ID_TEXTCTRL_BODY_MAT), wxTextCtrl);
    mHandTextMatCtrl = wxDynamicCast(this->FindWindow(ID_TEXTCTRL_HAND_MAT), wxTextCtrl);
    mFootTextMatCtrl = wxDynamicCast(this->FindWindow(ID_TEXTCTRL_FOOT_MAT), wxTextCtrl);

    mColourButton = wxDynamicCast(this->FindWindow(ID_BUTTON_COLOUR), wxButton);

	mCheckBoxLoop->SetValue(mDObject->getAnimationLoop());

	for ( unsigned short i = 0; i < mDObject->getSkeletonAnimationCount(); ++i )
	{
		Ogre::Animation *anim = mDObject->getSkeletonAnimation(i);

		if ( anim )
		{
			wxString nameStr(anim->getName().c_str());
			mListBoxAnimation->InsertItems( 1, &nameStr, 0 );            
		}
	}

    // 加入obj中定义的动作名称
    WX::LogicModelManager::AnimationSkeletonLinksIterator asmIt = 
        WX::LogicModelManager::getSingleton().getAnimationSkeletonLinksIterator(mDObject->getName());

    while ( asmIt.hasMoreElements() )
    {
        wxString animName(asmIt.peekNextKey().c_str());

        if ( wxNOT_FOUND == mListBoxAnimation->FindString(animName) )
        {
            wxString nameStr(animName.c_str());
            mListBoxAnimation->InsertItems( 1, &nameStr, 0 );
        }

        asmIt.moveNext();
    }

    if ( NULL == WX::LogicModel::GetPlaySoundFuncton() )
	{
		WX::LogicModel::SetPlaySoundFuncton(wxGetApp().funcPlay);
	}
	
	if ( NULL == WX::LogicModel::GetStopSoundFunction() )
		WX::LogicModel::SetStopSoundFunction(wxGetApp().funcStop);

	FillAllSkillListBox();
}
void MilkshapePlugin::doExportAnimations(msModel* pModel, Ogre::SkeletonPtr& ogreskel)
{

    Ogre::LogManager& logMgr = Ogre::LogManager::getSingleton();
    std::vector<SplitAnimationStruct> splitInfo;
    Ogre::String msg;

    int numFrames = msModel_GetTotalFrames(pModel);
	msg = "Number of frames: " + Ogre::StringConverter::toString(numFrames);
    logMgr.logMessage(msg);

    if (splitAnimations)
    {
        // Explain
        msg = "You have chosen to create multiple discrete animations by splitting up the frames in "
			"the animation sequence. In order to do this, you must supply a simple text file "
            "describing the separate animations, which has a single line per animation in the format: \n\n" 
            "startFrame,endFrame,animationName\n\nFor example: \n\n"
            "1,20,Walk\n21,35,Run\n36,40,Shoot\n\n" 
            "..creates 3 separate animations (the frame numbers are inclusive)."
			"You must browse to this file in the next dialog.";
        MessageBox(0,msg.c_str(), "Splitting Animations",MB_ICONINFORMATION | MB_OK);
        // Prompt for a file which contains animation splitting info
        OPENFILENAME ofn;
        memset (&ofn, 0, sizeof (OPENFILENAME));
        
        char szFile[MS_MAX_PATH];
        char szFileTitle[MS_MAX_PATH];
        char szDefExt[32] = "skeleton";
        char szFilter[128] = "All Files (*.*)\0*.*\0\0";
        szFile[0] = '\0';
        szFileTitle[0] = '\0';

        ofn.lStructSize = sizeof (OPENFILENAME);
        ofn.lpstrDefExt = szDefExt;
        ofn.lpstrFilter = szFilter;
        ofn.lpstrFile = szFile;
        ofn.nMaxFile = MS_MAX_PATH;
        ofn.lpstrFileTitle = szFileTitle;
        ofn.nMaxFileTitle = MS_MAX_PATH;
        ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
        ofn.lpstrTitle = "Open animation split configuration file";

        if (!::GetOpenFileName (&ofn))
        {
            msg = "Splitting aborted, generating a single animation called 'Default'";
            MessageBox(0, msg.c_str(), "Info", MB_OK | MB_ICONWARNING);
            SplitAnimationStruct split;
            split.start = 1;
            split.end = numFrames;
            split.name = "Default";
            splitInfo.push_back(split);
        }
        else
        {
            // Read file
            Ogre::String sline;
            char line[256];
            SplitAnimationStruct newSplit;

            std::ifstream istr;
            istr.open(szFile);

            while (!istr.eof())
            {
                istr.getline(line, 256);
                sline = line;

                // Ignore blanks & comments
                if (sline == "" || sline.substr(0,2) == "//")
                    continue;

                // Split on ','
				std::vector<Ogre::String> svec = Ogre::StringUtil::split(line, ",\n");

                // Basic validation on number of elements
                if (svec.size() != 3)
                {
                    MessageBox(0, "Warning: corrupt animation details in file. You should look into this. ",
                        "Corrupt animations file", MB_ICONWARNING | MB_OK);
                    continue;
                }
                // Remove any embedded spaces
				Ogre::StringUtil::trim(svec[0]);
                Ogre::StringUtil::trim(svec[1]);
                Ogre::StringUtil::trim(svec[2]);
                // Create split info
                newSplit.start = atoi(svec[0].c_str());
                newSplit.end = atoi(svec[1].c_str());
                newSplit.name = svec[2];
                splitInfo.push_back(newSplit);

            }


        }

    }
    else
    {
        // No splitting
        SplitAnimationStruct split;
        split.start = 1;
        split.end = numFrames;
        split.name = "Default";
        splitInfo.push_back(split);
    }

    // Get animation length
    // Map frames -> seconds, this can be changed in speed of animation anyway



    int numBones = msModel_GetBoneCount(pModel);
    unsigned int frameTime;
    float realTime;

    std::vector<SplitAnimationStruct>::iterator animsIt;
    for (animsIt = splitInfo.begin(); animsIt != splitInfo.end(); ++animsIt)
    {
        SplitAnimationStruct& currSplit = *animsIt;

        // Create animation
        frameTime = currSplit.end - currSplit.start;
        realTime = frameTime / fps;
		Ogre::LogManager::getSingleton().stream()
			<< "Trying to create Animation object for animation "
			<<  currSplit.name << " For Frames " << currSplit.start << " to "
            << currSplit.end << " inclusive. ";

		Ogre::LogManager::getSingleton().stream()
			<< "Frame time = "
			<< frameTime << ", Seconds = " << realTime;

        Ogre::Animation *ogreanim =
            ogreskel->createAnimation(currSplit.name, realTime);
        logMgr.logMessage("Animation object created.");

        int i;
        // Create all the animation tracks
        for (i = 0; i < numBones; ++i)
        {

            msBone* bone = msModel_GetBoneAt(pModel, i);
            Ogre::Bone* ogrebone = ogreskel->getBone(bone->szName);

            // Create animation tracks
			msg = "Creating AnimationTrack for bone " + Ogre::StringConverter::toString(i);
            logMgr.logMessage(msg);

            Ogre::NodeAnimationTrack *ogretrack = ogreanim->createNodeTrack(i, ogrebone);
            logMgr.logMessage("Animation track created.");

            // OGRE uses keyframes which are both position and rotation
            // Milkshape separates them, but never seems to use the ability to
            // have a different # of pos & rot keys

            int numKeys = msBone_GetRotationKeyCount(bone);

            msg = "Number of keyframes: " + Ogre::StringConverter::toString(numKeys);
            logMgr.logMessage(msg);

            int currKeyIdx;
            msPositionKey* currPosKey;
            msRotationKey* currRotKey;
            for (currKeyIdx = 0; currKeyIdx < numKeys; ++currKeyIdx )
            {
                currPosKey = msBone_GetPositionKeyAt(bone, currKeyIdx);
                currRotKey = msBone_GetRotationKeyAt(bone, currKeyIdx);

                // Make sure keyframe is in current time frame (for splitting)
                if (currRotKey->fTime >= currSplit.start && currRotKey->fTime <= currSplit.end)
                {

                    msg = "Creating KeyFrame #" + Ogre::StringConverter::toString(currKeyIdx)
                        + " for bone #" + Ogre::StringConverter::toString(i);
                    logMgr.logMessage(msg);
                    // Create keyframe
                    // Adjust for start time, and for the fact that frames are numbered from 1
                    frameTime = currRotKey->fTime - currSplit.start;
                    realTime = frameTime / fps;
                    Ogre::TransformKeyFrame *ogrekey = ogretrack->createNodeKeyFrame(realTime);
                    logMgr.logMessage("KeyFrame created");

					Ogre::Vector3 kfPos;
					// Imported milkshape animations may not have positions 
					// for all rotation keys
					if ( currKeyIdx < bone->nNumPositionKeys ) {
						kfPos.x = currPosKey->Position[0];
						kfPos.y = currPosKey->Position[1];
						kfPos.z = currPosKey->Position[2];
					}
					else {
						kfPos.x = bone->Position[0];
						kfPos.y = bone->Position[1];
						kfPos.z = bone->Position[2];
					}
                    Ogre::Quaternion qx, qy, qz, kfQ;

					// Milkshape translations are local to own orientation, not parent
					kfPos = ogrebone->getOrientation() * kfPos;

                    ogrekey->setTranslate(kfPos);
                    qx.FromAngleAxis(Ogre::Radian(currRotKey->Rotation[0]), Ogre::Vector3::UNIT_X);
                    qy.FromAngleAxis(Ogre::Radian(currRotKey->Rotation[1]), Ogre::Vector3::UNIT_Y);
                    qz.FromAngleAxis(Ogre::Radian(currRotKey->Rotation[2]), Ogre::Vector3::UNIT_Z);
                    kfQ = qz * qy * qx;
                    ogrekey->setRotation(kfQ);

					Ogre::LogManager::getSingleton().stream()
						<< "KeyFrame details: Adjusted Frame Time=" << frameTime
						<< " Seconds: " << realTime << " Position=" << kfPos << " " 
						<< "Ms3d Rotation= {" << currRotKey->Rotation[0] << ", " 
						<< currRotKey->Rotation[1] << ", " << currRotKey->Rotation[2] 
						<< "} " << "Orientation=" << kfQ;
                } // keyframe creation

            } // keys
        } //Bones
    } // Animations




}
void CSceletalAnimationView::EngineSetup(void)
{
	Ogre::Root *Root = ((CSceletalAnimationApp*)AfxGetApp())->m_Engine->GetRoot();
	Ogre::SceneManager *SceneManager = NULL;
	SceneManager = Root->createSceneManager(Ogre::ST_GENERIC, "Animation");
 
    //
    // Create a render window
    // This window should be the current ChildView window using the externalWindowHandle
    // value pair option.
    //

    Ogre::NameValuePairList parms;
    parms["externalWindowHandle"] = Ogre::StringConverter::toString((long)m_hWnd);
    parms["vsync"] = "true";

	CRect   rect;
    GetClientRect(&rect);
	Ogre::RenderTarget *RenderWindow = Root->getRenderTarget("Mouse Input");

	if (RenderWindow == NULL)
	{
	try
	{
		m_RenderWindow = Root->createRenderWindow("Mouse Input", rect.Width(), rect.Height(), false, &parms);
	}
    catch(...)
	{
		MessageBox("Cannot initialize\nCheck that graphic-card driver is up-to-date", "Initialize Render System", MB_OK | MB_ICONSTOP);
		exit(EXIT_SUCCESS);
	}
	}
// Load resources
	Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

    // Create the camera
    m_Camera = SceneManager->createCamera("Camera");
    m_Camera->setNearClipDistance(0.5);
	m_Camera->setFarClipDistance(5000); 
	m_Camera->setCastShadows(false);
	m_Camera->setUseRenderingDistance(true);
	m_Camera->setPosition(Ogre::Vector3(5.0, 5.0, 10.0));
	Ogre::SceneNode *CameraNode = NULL;
	CameraNode = SceneManager->getRootSceneNode()->createChildSceneNode("CameraNode");

	Ogre::Viewport* Viewport = NULL;
	
	if (0 == m_RenderWindow->getNumViewports())
	{
		Viewport = m_RenderWindow->addViewport(m_Camera);
		Viewport->setBackgroundColour(Ogre::ColourValue(0.8f, 0.8f, 0.8f));
	}

    // Alter the camera aspect ratio to match the viewport
    m_Camera->setAspectRatio(Ogre::Real(rect.Width()) / Ogre::Real(rect.Height()));
	m_Camera->lookAt(Ogre::Vector3(0.5, 0.5, 0.5));
	m_Camera->setPolygonMode(Ogre::PolygonMode::PM_WIREFRAME);

	Ogre::ManualObject* ManualObject = NULL;
	ManualObject = SceneManager->createManualObject("Animation");
	ManualObject->setDynamic(false);
    ManualObject->begin("BaseWhiteNoLighting", Ogre::RenderOperation::OT_TRIANGLE_LIST);
	//face 1
	ManualObject->position(0, 0, 0);//0
	ManualObject->position(1, 0, 0);//1
	ManualObject->position(1, 1, 0);//2
	ManualObject->triangle(0, 1, 2);//3
	
	ManualObject->position(0, 0, 0);//4
	ManualObject->position(1, 1, 0);//5
	ManualObject->position(0, 1, 0);//6
	ManualObject->triangle(3, 4, 5);//7
	//face 2
	ManualObject->position(0, 0, 1);//8
	ManualObject->position(1, 0, 1);//9
	ManualObject->position(1, 1, 1);//10
	ManualObject->triangle(6, 7, 8);//11

	ManualObject->position(0, 0, 1);//12
	ManualObject->position(1, 1, 1);//13
	ManualObject->position(0, 1, 1);//14
	ManualObject->triangle(9, 10, 11);//15
	//face 3
	ManualObject->position(0, 0, 0);//16
	ManualObject->position(1, 0, 0);//17
	ManualObject->position(1, 0, 1);//18
	ManualObject->triangle(12, 13, 14);//19

	ManualObject->position(0, 0, 0);
	ManualObject->position(1, 0, 1);
	ManualObject->position(0, 1, 1);
	ManualObject->triangle(15, 16, 17);
	//face 4
	ManualObject->position(1, 0, 0);
	ManualObject->position(1, 1, 0);
	ManualObject->position(1, 1, 1);
	ManualObject->triangle(18, 19, 20);

	ManualObject->position(1, 0, 0);
	ManualObject->position(1, 1, 1);
	ManualObject->position(1, 0, 1);
	ManualObject->triangle(21, 22, 23);
	//face 5
	ManualObject->position(0, 1, 0);
	ManualObject->position(1, 1, 0);
	ManualObject->position(0, 1, 1);
	ManualObject->triangle(24, 25, 26);

	ManualObject->position(1, 1, 0);
	ManualObject->position(1, 1, 1);
	ManualObject->position(0, 1, 1);
	ManualObject->triangle(27, 28, 29);
	
	//face 6
	ManualObject->position(0, 0, 0);
	ManualObject->position(0, 1, 1);
	ManualObject->position(0, 0, 1);
	ManualObject->triangle(30, 31, 32);

	ManualObject->position(0, 0, 0);
	ManualObject->position(0, 1, 0);
	ManualObject->position(0, 1, 1);
	ManualObject->triangle(33, 34, 35);

	ManualObject->end();
	Ogre::MeshPtr MeshPtr = ManualObject->convertToMesh("Animation");
	Ogre::SubMesh* sub = MeshPtr->getSubMesh(0);
	
	Ogre::SkeletonPtr Skeleton = Ogre::SkeletonManager::getSingleton().create("Skeleton", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
	MeshPtr.getPointer()->_notifySkeleton(Skeleton);
	Ogre::Bone *Root1 = NULL;
	Ogre::Bone *Child1 = NULL;
	Ogre::Bone *Child2 = NULL;

	Root1 = Skeleton.getPointer()->createBone("Root");
	Root1->setPosition(Ogre::Vector3(0.0, 0.0, 0.0));
	Root1->setOrientation(Ogre::Quaternion::IDENTITY);
	
	Child1 = Root1->createChild(1);
	Child1->setPosition(Ogre::Vector3(4.0, 0.0, 0.0));
	Child1->setOrientation(Ogre::Quaternion::IDENTITY);
	Child2 = Root1->createChild(2);
	Child2->setPosition(Ogre::Vector3(5.0, 0.0, 0.0));
	Child2->setOrientation(Ogre::Quaternion::IDENTITY);

	Ogre::VertexBoneAssignment Assignment;

	Assignment.boneIndex = 0;
	Assignment.vertexIndex = 0;
	Assignment.weight = 1.0;
	Skeleton->setBindingPose();

	sub->addBoneAssignment(Assignment);

	Assignment.vertexIndex = 1;
	sub->addBoneAssignment(Assignment);

	Assignment.vertexIndex = 2;
	sub->addBoneAssignment(Assignment);

	Ogre::Animation *Animation = MeshPtr->createAnimation("HandAnimation", 100.0);
	Ogre::NodeAnimationTrack *Track = Animation->createNodeTrack(0, Root1);
	Ogre::TransformKeyFrame *KeyFrame = NULL;

	for (float FrameTime = 0.0; FrameTime < 100.0; FrameTime += 0.1)
	{
		KeyFrame = Track->createNodeKeyFrame(FrameTime);
		KeyFrame->setTranslate(Ogre::Vector3(10.0, 0.0, 0.0));
	}

	Root1->setManuallyControlled(true);
	Child1->setManuallyControlled(true);
	Child2->setManuallyControlled(true);
	MeshPtr->load();

	MeshPtr.getPointer()->_notifySkeleton(Skeleton);
		
//	Ogre::SkeletonSerializer skeletonSerializer;
//	skeletonSerializer.exportSkeleton(Skeleton.get(), "C:\\Users\\Ilya\\Documents\\Visual Studio 2010\\Projects\\Recipes\\media\\models\\testskeleton.skeleton");
//	Ogre::MeshSerializer ser;
//    ser.exportMesh(MeshPtr.get(), "C:\\Users\\Ilya\\Documents\\Visual Studio 2010\\Projects\\Recipes\\media\\models\\testskeleton.mesh");

	Ogre::Entity *Entity = SceneManager->createEntity("Animation", "Animation"/*"testskeleton.mesh"*/);
	Ogre::SceneNode *SceneNode = SceneManager->getRootSceneNode()->createChildSceneNode();
	SceneNode->attachObject(Entity);
	Entity->setDisplaySkeleton(true);

	m_AnimationState = Entity->getAnimationState("HandAnimation");
	m_AnimationState->setEnabled(true);
	m_AnimationState->setLoop(true);
	
	m_Camera->setPolygonMode(Ogre::PolygonMode::PM_WIREFRAME);
	 
	Root->renderOneFrame();
}
    void EC_OgreAnimationController::Update(f64 frametime)
    {
        Ogre::Entity* entity = GetEntity();
        if (!entity) return;
        
        std::vector<std::string> erase_list;
        
        // Loop through all animations & update them as necessary
        for (AnimationMap::iterator i = animations_.begin(); i != animations_.end(); ++i)
        {
            Ogre::AnimationState* animstate = GetAnimationState(entity, i->first);
            if (!animstate)
                continue;
                
            switch(i->second.phase_)
            {
            case PHASE_FADEIN:
                // If period is infinitely fast, skip to full weight & PLAY status
                if (i->second.fade_period_ == 0.0f)
                {
                    i->second.weight_ = 1.0f;
                    i->second.phase_ = PHASE_PLAY;
                }   
                else
                {
                    i->second.weight_ += (1.0f / i->second.fade_period_) * frametime;
                    if (i->second.weight_ >= 1.0f)
                    {
                        i->second.weight_ = 1.0f;
                        i->second.phase_ = PHASE_PLAY;
                    }
                }
                break;

            case PHASE_PLAY:
                if (i->second.auto_stop_ || i->second.num_repeats_ != 1)
                {
                    if ((i->second.speed_factor_ >= 0.f && animstate->getTimePosition() >= animstate->getLength()) ||
                        (i->second.speed_factor_ < 0.f && animstate->getTimePosition() <= 0.f))
                    {
                        if (i->second.num_repeats_ != 1)
                        {
                            if (i->second.num_repeats_ > 1)
                                i->second.num_repeats_--;

                            Ogre::Real rewindpos = i->second.speed_factor_ >= 0.f ? (animstate->getTimePosition() - animstate->getLength()) : animstate->getLength();
                            animstate->setTimePosition(rewindpos);
                        }
                        else
                        {
                            i->second.phase_ = PHASE_FADEOUT;
                        }
                    }
                }
                break;	

            case PHASE_FADEOUT:
                // If period is infinitely fast, skip to disabled status immediately
                if (i->second.fade_period_ == 0.0f)
                {
                    i->second.weight_ = 0.0f;
                    i->second.phase_ = PHASE_STOP;
                }
                else
                {
                    i->second.weight_ -= (1.0f / i->second.fade_period_) * frametime;
                    if (i->second.weight_ <= 0.0f)
                    {
                        i->second.weight_ = 0.0f;
                        i->second.phase_ = PHASE_STOP;
                    }
                }
                break;
            }

            // Set weight & step the animation forward
            if (i->second.phase_ != PHASE_STOP)
            {
                Ogre::Real advance = i->second.speed_factor_ * frametime;
                Ogre::Real new_weight = i->second.weight_ * i->second.weight_factor_;
                
                if (new_weight != animstate->getWeight())
                    animstate->setWeight((Ogre::Real)i->second.weight_ * i->second.weight_factor_);
                if (advance != 0.0f)
                    animstate->addTime((Ogre::Real)(i->second.speed_factor_ * frametime));
                if (!animstate->getEnabled())
                    animstate->setEnabled(true);
            }
            else
            {
                // If stopped, disable & remove this animation from list
                animstate->setEnabled(false);
                erase_list.push_back(i->first);
            }
        }
        
        for (uint i = 0; i < erase_list.size(); ++i)
        {
            animations_.erase(erase_list[i]);
        }
        
        // High-priority/low-priority blending code
        if (entity->hasSkeleton())
        {
            Ogre::SkeletonInstance* skel = entity->getSkeleton();
            if (!skel)
                return;
                
		    if (highpriority_mask_.size() != skel->getNumBones())
			    highpriority_mask_.resize(skel->getNumBones());
		    if (lowpriority_mask_.size() != skel->getNumBones())
			    lowpriority_mask_.resize(skel->getNumBones());

            for (uint i = 0; i < skel->getNumBones(); ++i)
            {
                highpriority_mask_[i] = 1.0;
                lowpriority_mask_[i] = 1.0;
            }

		    // Loop through all high priority animations & update the lowpriority-blendmask based on their active tracks
            for (AnimationMap::iterator i = animations_.begin(); i != animations_.end(); ++i)
	        {
                Ogre::AnimationState* animstate = GetAnimationState(entity, i->first);
                if (!animstate)
                    continue;	        
                // Create blend mask if animstate doesn't have it yet
                if (!animstate->hasBlendMask())
                    animstate->createBlendMask(skel->getNumBones());

                if ((i->second.high_priority_) && (i->second.weight_ > 0.0))
                {
				    // High-priority animations get the full weight blend mask
                    animstate->_setBlendMaskData(&highpriority_mask_[0]);
                    if (!skel->hasAnimation(animstate->getAnimationName()))
                        continue;
                        
                    Ogre::Animation* anim = skel->getAnimation(animstate->getAnimationName());
                    
                    Ogre::Animation::NodeTrackIterator it = anim->getNodeTrackIterator();
                    while (it.hasMoreElements())
                    {
					    Ogre::NodeAnimationTrack* track = it.getNext();
					    unsigned id = track->getHandle();
					    // For each active track, reduce corresponding bone weight in lowpriority-blendmask 
					    // by this animation's weight
					    if (id < lowpriority_mask_.size())
					    {
						    lowpriority_mask_[id] -= i->second.weight_;
						    if (lowpriority_mask_[id] < 0.0) lowpriority_mask_[id] = 0.0;
					    }
			        }
                }
            }

		    // Now set the calculated blendmask on low-priority animations
            for (AnimationMap::iterator i = animations_.begin(); i != animations_.end(); ++i)
	        {
                Ogre::AnimationState* animstate = GetAnimationState(entity, i->first);
                if (!animstate)
                    continue;	
                if (i->second.high_priority_ == false)	        
                    animstate->_setBlendMaskData(&lowpriority_mask_[0]);			    			   
		    }
        }
    }
Beispiel #12
0
/* Function used to load an AnimationState to a sceneNode.
 * Params:
 * 	@scnManager		the SceneManager
 * 	@node			The SceneNode to load the AnimationStates
 * 	@elem			The TiXmlElement where is the animation
 * Returns:
 * 	anim			On success
 * 	0				On error
 */
bool Util::getAnimation(Ogre::SceneManager *scnManager,
		Ogre::SceneNode *node,
		TiXmlElement *elem,
		std::list<Ogre::AnimationState *> &animList)
{
	ASSERT(scnManager);
	ASSERT(node);
	ASSERT(elem);

	if(Ogre::String(elem->Value()) != "animations") {
		debug("Invalid animation xml: %s \n", elem->Value());
		return false;
	}
	animList.clear();

	TiXmlElement *pElement = elem->FirstChildElement("animation");
	if(!pElement){
		debug("No animations found\n");
		return false;
	}
	while(pElement){
		TiXmlElement *actualElement = pElement;
		Ogre::String nombreanimacion = actualElement->Attribute("name");
		Ogre::String activada = actualElement->Attribute("enable");
		Ogre::String loop = actualElement->Attribute("loop");
		Ogre::String modointerpolacion = actualElement->Attribute("interpolationMode");
		Ogre::String modointerpolacionrotacion = actualElement->Attribute("rotationInterpolationMode");
		Ogre::Real longitud= Ogre::StringConverter::parseReal(actualElement->Attribute("length"));

		Ogre::SceneManager *sceneMgr = scnManager;
		Ogre::Animation *animrueda = sceneMgr->createAnimation(nombreanimacion,longitud);

		if (modointerpolacion == "spline") {
			animrueda->setInterpolationMode(Ogre::Animation::IM_SPLINE);
		} else //linear
		{
			animrueda->setInterpolationMode(Ogre::Animation::IM_LINEAR);
		}

		if (modointerpolacionrotacion == "spherical") {
			animrueda->setRotationInterpolationMode(Ogre::Animation::RIM_SPHERICAL);
		} else //linear
		{
			animrueda->setRotationInterpolationMode(Ogre::Animation::RIM_LINEAR);
		}

		Ogre::NodeAnimationTrack *track = animrueda->createNodeTrack(
				animrueda->getNumNodeTracks() + 1, node);

		actualElement = actualElement->FirstChildElement();
		do {
			Ogre::Real tiempo = Ogre::StringConverter::parseReal(
					actualElement->Attribute("time"));
			Ogre::TransformKeyFrame *kf = track->createNodeKeyFrame(tiempo);

			kf->setTranslate(
					parseVector3(actualElement->FirstChildElement("translation")));
			kf->setRotation(
					parseQuaternion(
							actualElement->FirstChildElement("rotation")));
			kf->setScale(
					parseVector3(
							actualElement->FirstChildElement("scale")));

		} while (actualElement = actualElement->NextSiblingElement());

		// Create the animation and put it in the list
		Ogre::AnimationState *as = scnManager->createAnimationState(nombreanimacion);
		as->setEnabled(false);
		as->setLoop(false);
		ASSERT(as);
		animList.push_back(as);
		pElement = pElement->NextSiblingElement("animation");
	}


	return true;
}
Beispiel #13
0
void
AnimationFile::GetData( std::vector< s16 >& skeleton_length, const Unit& unit, const int offset_to_animations, const int number_of_animation, const int start_animation, Ogre::SkeletonPtr skeleton)
{
    for (int i = 0; i < number_of_animation; ++i)
    {
        /*LOGGER->Log(LOGGER_INFO, "Animation Header %02x%02x %02x %02x %02x %02x %02x%02x %02x%02x %02x%02x %02x%02x%02x%02x",
                    GetU8(offset_to_animations + i * 0x10 + 0x00), GetU8(offset_to_animations + i * 0x10 + 0x01), GetU8(offset_to_animations + i * 0x10 + 0x02), GetU8(offset_to_animations + i * 0x10 + 0x03),
                    GetU8(offset_to_animations + i * 0x10 + 0x04), GetU8(offset_to_animations + i * 0x10 + 0x05), GetU8(offset_to_animations + i * 0x10 + 0x06), GetU8(offset_to_animations + i * 0x10 + 0x07),
                    GetU8(offset_to_animations + i * 0x10 + 0x08), GetU8(offset_to_animations + i * 0x10 + 0x09), GetU8(offset_to_animations + i * 0x10 + 0x0A), GetU8(offset_to_animations + i * 0x10 + 0x0B),
                    GetU8(offset_to_animations + i * 0x10 + 0x0C), GetU8(offset_to_animations + i * 0x10 + 0x0D), GetU8(offset_to_animations + i * 0x10 + 0x0E), GetU8(offset_to_animations + i * 0x10 + 0x0F));
        */
        AnimationHeader header;
        header.number_of_frames                  = GetU16LE(offset_to_animations + i * 0x10 + 0x00);
        header.number_of_bones                   = GetU8(offset_to_animations + i * 0x10 + 0x02);
        header.number_of_frames_translation      = GetU8(offset_to_animations + i * 0x10 + 0x03);
        header.number_of_static_translation      = GetU8(offset_to_animations + i * 0x10 + 0x04);
        header.number_of_frames_rotation         = GetU8(offset_to_animations + i * 0x10 + 0x05);
        header.offset_to_frames_translation_data = GetU16LE(offset_to_animations + i * 0x10 + 0x06);
        header.offset_to_static_translation_data = GetU16LE(offset_to_animations + i * 0x10 + 0x08);
        header.offset_to_frames_rotation_data    = GetU16LE(offset_to_animations + i * 0x10 + 0x0A);
        header.offset_to_animation_data          = GetU32LE(offset_to_animations + i * 0x10 + 0x0C) - 0x80000000;
        m_AnimationHeaders.push_back(header);
    }

    for (size_t i = 0; (i < static_cast<size_t>(number_of_animation)) && (start_animation + i < unit.animations.size()); ++i)
    {
        if (unit.animations[start_animation + i] == "" || unit.animations[start_animation + i] == " ")
        {
            continue;
        }

        /*
        File file(mpBuffer, m_AnimationHeaders[i].offset_to_animation_data, 0x04 + m_AnimationHeaders[i].number_of_bones * 0x08 + m_AnimationHeaders[i].number_of_frames_translation * m_AnimationHeaders[i].number_of_frames * 0x02 + m_AnimationHeaders[i].number_of_static_translation * 0x02 + m_AnimationHeaders[i].number_of_frames_rotation * m_AnimationHeaders[i].number_of_frames);
        file.WriteFile(RString((Ogre::String("dump/") + Ogre::String("animation_") + Ogre::StringConverter::toString(i) + Ogre::String("_data")).c_str()));
        */

        Ogre::Animation* anim = skeleton->createAnimation(unit.animations[start_animation + i], (float)(m_AnimationHeaders[i].number_of_frames - 1) / 30.0f);

        for (u32 j = 0; j < m_AnimationHeaders[i].number_of_frames; ++j)
        {
            Frame frame;

            // root bone
            Ogre::Bone* root = skeleton->getBone(0);

            Ogre::NodeAnimationTrack* track;
            if (j == 0)
            {
                track = anim->createNodeTrack(0, root);
                track->removeAllKeyFrames();
            }
            else
            {
                track = anim->getNodeTrack(0);
            }

            Ogre::TransformKeyFrame* frame_root = track->createNodeKeyFrame((float)j / 30.0f);

            Ogre::Quaternion rot;
            Ogre::Matrix3 mat;
            mat.FromEulerAnglesZXY(Ogre::Radian(Ogre::Degree(180)), Ogre::Radian(Ogre::Degree(0)), Ogre::Radian(Ogre::Degree(0)));
            rot.FromRotationMatrix(mat);
            frame_root->setRotation(rot);

            for (u32 k = 0; k < m_AnimationHeaders[i].number_of_bones; ++k)
            {
                BonePosition position;

                u8 flag = GetU8(m_AnimationHeaders[i].offset_to_animation_data + 0x04 + k * 0x08 + 0x00);

                u8 rx = GetU8(m_AnimationHeaders[i].offset_to_animation_data + 0x04 + k * 0x08 + 0x01);
                u8 ry = GetU8(m_AnimationHeaders[i].offset_to_animation_data + 0x04 + k * 0x08 + 0x02);
                u8 rz = GetU8(m_AnimationHeaders[i].offset_to_animation_data + 0x04 + k * 0x08 + 0x03);
                u8 tx = GetU8(m_AnimationHeaders[i].offset_to_animation_data + 0x04 + k * 0x08 + 0x04);
                u8 ty = GetU8(m_AnimationHeaders[i].offset_to_animation_data + 0x04 + k * 0x08 + 0x05);
                u8 tz = GetU8(m_AnimationHeaders[i].offset_to_animation_data + 0x04 + k * 0x08 + 0x06);

                // rotation
                if (flag & 0x01)
                {
                    position.rotation_x = 360.0f * GetU8(m_AnimationHeaders[i].offset_to_animation_data + m_AnimationHeaders[i].offset_to_frames_rotation_data + rx * m_AnimationHeaders[i].number_of_frames + j) / 255.0f;
                }
                else
                {
                    position.rotation_x = 360.0f * rx / 255.0f;
                }

                if (flag & 0x02)
                {
                    position.rotation_y = 360.0f * GetU8(m_AnimationHeaders[i].offset_to_animation_data + m_AnimationHeaders[i].offset_to_frames_rotation_data + ry * m_AnimationHeaders[i].number_of_frames + j) / 255.0f;
                }
                else
                {
                    position.rotation_y = 360.0f * ry / 255.0f;
                }

                if (flag & 0x04)
                {
                    position.rotation_z = 360.0f * GetU8(m_AnimationHeaders[i].offset_to_animation_data + m_AnimationHeaders[i].offset_to_frames_rotation_data + rz * m_AnimationHeaders[i].number_of_frames + j) / 255.0f;
                }
                else
                {
                    position.rotation_z = 360.0f * rz / 255.0f;
                }

                // translation
                position.translation_x = 0;
                position.translation_y = 0;
                position.translation_z = 0;

                if (flag & 0x10)
                {
                    position.translation_x = static_cast<float>( -(s16)GetU16LE(m_AnimationHeaders[i].offset_to_animation_data + m_AnimationHeaders[i].offset_to_frames_translation_data + tx * m_AnimationHeaders[i].number_of_frames * 2 + j * 2));
                }
                else if (tx != 0xFF)
                {
                    position.translation_x = static_cast<float>(-(s16)GetU16LE(m_AnimationHeaders[i].offset_to_animation_data + m_AnimationHeaders[i].offset_to_static_translation_data + tx * 2));
                }

                if (flag & 0x20)
                {
                    position.translation_y = static_cast<float>(-(s16)GetU16LE(m_AnimationHeaders[i].offset_to_animation_data + m_AnimationHeaders[i].offset_to_frames_translation_data + ty * m_AnimationHeaders[i].number_of_frames * 2 + j * 2));
                }
                else if (ty != 0xFF)
                {
                    position.translation_y = static_cast<float>(-(s16)GetU16LE(m_AnimationHeaders[i].offset_to_animation_data + m_AnimationHeaders[i].offset_to_static_translation_data + ty * 2));
                }

                if (flag & 0x40)
                {
                    position.translation_z = static_cast<float>(-(s16)GetU16LE(m_AnimationHeaders[i].offset_to_animation_data + m_AnimationHeaders[i].offset_to_frames_translation_data + tz * m_AnimationHeaders[i].number_of_frames * 2 + j * 2));
                }
                else if (tz != 0xFF)
                {
                    position.translation_z = static_cast<float>(-(s16)GetU16LE(m_AnimationHeaders[i].offset_to_animation_data + m_AnimationHeaders[i].offset_to_static_translation_data + tz * 2));
                }

                //LOGGER->Log(LOGGER_INFO, "%d %d", m_AnimationHeaders[i].number_of_frames, j);
                //LOGGER->Log(LOGGER_INFO, "animation (%f %f %f) (%f %f %f)", position.rotation_x, position.rotation_y, position.rotation_z, position.translation_x, position.translation_y, position.translation_z);

                frame.bone.push_back(position);

                Ogre::Bone* bone1 = skeleton->getBone(k * 2 + 1);
                Ogre::Bone* bone2 = skeleton->getBone(k * 2 + 2);

                Ogre::NodeAnimationTrack* track1;
                Ogre::NodeAnimationTrack* track2;
                if (j == 0)
                {
                    track1 = anim->createNodeTrack(k * 2 + 1, bone1);
                    track1->removeAllKeyFrames();
                    track2 = anim->createNodeTrack(k * 2 + 2, bone2);
                    track2->removeAllKeyFrames();
                }
                else
                {
                    track1 = anim->getNodeTrack(k * 2 + 1);
                    track2 = anim->getNodeTrack(k * 2 + 2);
                }

                Ogre::TransformKeyFrame* frame1 = track1->createNodeKeyFrame((float)j / 30.0f);
                Ogre::TransformKeyFrame* frame2 = track2->createNodeKeyFrame((float)j / 30.0f);

                float length = skeleton_length[ k ];

                frame1->setTranslate(Ogre::Vector3(position.translation_x, position.translation_z - length, position.translation_y) / 1024);

                Ogre::Quaternion rot;
                Ogre::Matrix3 mat;
                mat.FromEulerAnglesZXY(Ogre::Radian(Ogre::Degree(-position.rotation_y)), Ogre::Radian(Ogre::Degree(-position.rotation_x)), Ogre::Radian(Ogre::Degree(-position.rotation_z)));
                rot.FromRotationMatrix(mat);
                frame2->setRotation(rot);
            }
        }
    }
}
Beispiel #14
0
Ogre::Entity*
StageFile::GetModel( const StageInfo& info )
{
    //DumpSettings("exported/" + info.data.name + ".lua");

    VectorTexForGen textures;
    Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().create(info.data.name + "export", "General");
    Ogre::SkeletonPtr skeleton = Ogre::SkeletonManager::getSingleton().create(info.data.name + "export", "General");

    u32 number_of_files = GetU32LE(0);
    LOGGER->Log("Number of file " + IntToString(number_of_files) + "\n");



    Ogre::Bone* root1 = skeleton->createBone( "0", 0 );
    Ogre::Bone* root2 = skeleton->createBone( "1", 1 );
    root1->addChild( root2 );

    Ogre::Animation* anim = skeleton->createAnimation( "Idle", 1 );
    Ogre::NodeAnimationTrack* track1 = anim->createNodeTrack( 0, root1 );
    track1->removeAllKeyFrames();
    Ogre::TransformKeyFrame* frame1 = track1->createNodeKeyFrame( 0 );
    Ogre::Matrix3 matrix;
    matrix.FromEulerAnglesYXZ( Ogre::Radian( Ogre::Degree( 0 ) ), Ogre::Radian( Ogre::Degree( -90 ) ), Ogre::Radian( Ogre::Degree( 0 ) ) );
    Ogre::Quaternion rot;
    rot.FromRotationMatrix( matrix );
    frame1->setRotation( rot );



    for (u32 i = 1; i < number_of_files - 1; ++i)
    {
        int offset_to_vertex = GetU32LE(0x04 + i * 0x04);
        MeshExtractor(info.data, "ffvii/battle_stage/" + info.data.name, this, offset_to_vertex, textures, mesh, Ogre::StringConverter::toString(i), 1);
    }



    // <OGRE> ///////////////////////////////
    skeleton->optimiseAllAnimations();
    Ogre::SkeletonSerializer skeleton_serializer;
    skeleton_serializer.exportSkeleton(skeleton.getPointer(), "exported/models/ffvii/battle/stages/" + info.data.name + ".skeleton");

    // Update bounds
    Ogre::AxisAlignedBox aabb(-999, -999, -999, 999, 999, 999);
    mesh->_setBounds(aabb, false);
    mesh->_setBoundingSphereRadius(999);

    mesh->setSkeletonName( "models/ffvii/battle/stages/" + info.data.name + ".skeleton" );

    Ogre::MeshSerializer ser;
    ser.exportMesh(mesh.getPointer(), "exported/models/ffvii/battle/stages/" + info.data.name + ".mesh");



    // create and export textures for model
    if( textures.size() > 0 )
    {
        int number_of_files = GetU32LE( 0x00 );
        int offset_to_texture = GetU32LE( number_of_files * 0x04 );
        Vram* vram = Vram::MakeInstance().release();

        LoadTimFileToVram( this, offset_to_texture, vram );
        //vram->Save( "qqq" );
        CreateTexture( vram, info.data, "exported/models/ffvii/battle/stages/" + info.data.name + ".png", textures );
        delete vram;
    }



    CreateMaterial("ffvii/battle_stage/" + info.data.name, "exported/models/ffvii/battle/stages/" + info.data.name + ".material", "models/ffvii/battle/stages/" + info.data.name + ".png", "", "");



    Ogre::SceneManager* scene_manager = Ogre::Root::getSingleton().getSceneManager( "Scene" );
    Ogre::Entity* thisEntity = scene_manager->createEntity( info.data.name, "models/ffvii/battle/stages/" + info.data.name + ".mesh" );
    //thisEntity->setDisplaySkeleton(true);
    //thisEntity->setDebugDisplayEnabled(true);
    thisEntity->setVisible(false);
    thisEntity->getAnimationState( "Idle" )->setEnabled( true );
    thisEntity->getAnimationState( "Idle" )->setLoop( true );
    Ogre::SceneNode* thisSceneNode = scene_manager->getRootSceneNode()->createChildSceneNode();
    thisSceneNode->setPosition( 0, 0, 0 );
    thisSceneNode->roll( Ogre::Radian( Ogre::Degree( 180.0f ) ) );
    thisSceneNode->yaw( Ogre::Radian( Ogre::Degree( 120.0f ) ) );
    thisSceneNode->pitch( Ogre::Radian( Ogre::Degree( 90.0f ) ) );
    thisSceneNode->attachObject( thisEntity );

    return thisEntity;
}