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 CameraTrackSettingDialog::OnModifyManual(wxCommandEvent& event) { if (mCameraTrack && mCameraAnimState) { int index = Ogre::StringConverter::parseUnsignedInt( mPointIndexTextCtrl->GetValue().c_str() ) - 1; if (index < mCameraTrack->getNumKeyFrames()) { mCameraTrack->removeKeyFrame(index); float time = Ogre::StringConverter::parseReal( mTimeTextCtrl->GetValue().c_str() ); if (time >=0.0f && time <= mCameraAnimState->getLength()) { Ogre::TransformKeyFrame* keyFrame = mCameraTrack->createNodeKeyFrame(time); // startposition keyFrame->setTranslate( Ogre::StringConverter::parseVector3( mPositionTextCtrl->GetValue().c_str() ) ); keyFrame->setRotation( Ogre::StringConverter::parseQuaternion( mOrientationTextCtrl->GetValue().c_str() ) ); RefreshCodeText(); } else { wxMessageBox(_("the time is wrong!")); } } else { wxMessageBox(_("the index is wrong!")); } } }
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; } } } } }
void CameraTrackSettingDialog::RefreshCodeText(void) { if (mCameraTrack) { mCodeText.Clear(); mCameraInfoListBox->Clear(); mModifySpinCtrl->SetValue("1"); mPointIndexTextCtrl->Clear(); mPositionTextCtrl->Clear(); mOrientationTextCtrl->Clear(); mTimeTextCtrl->Clear(); mCodeText += "Ogre::TransformKeyFrame* "; for (unsigned short index = 0; index < mCameraTrack->getNumKeyFrames(); ++index) { Ogre::TransformKeyFrame* keyFrame = static_cast<Ogre::TransformKeyFrame*>( mCameraTrack->getKeyFrame(index) ); const Ogre::Vector3& pos = keyFrame->getTranslate(); const Ogre::Quaternion& ori = keyFrame->getRotation(); float time = keyFrame->getTime(); mCodeText += "key = mCameraTrack->createNodeKeyFrame(" + Ogre::StringConverter::toString(time) + ");\n"; mCodeText += "key->setTranslate(Ogre::Vector3(" + Ogre::StringConverter::toString(pos.x) + "," + Ogre::StringConverter::toString(pos.y) + "," + Ogre::StringConverter::toString(pos.z) + "));\n"; mCodeText += "key->setRotation(Ogre::Quaternion(" + Ogre::StringConverter::toString(ori.w) + "," + Ogre::StringConverter::toString(ori.x) + "," + Ogre::StringConverter::toString(ori.y) + "," + Ogre::StringConverter::toString(ori.z) +"));\n"; // 刷新listbox mCameraInfoListBox->Append(Ogre::StringConverter::toString(pos) + "," + Ogre::StringConverter::toString(ori) + "," + Ogre::StringConverter::toString(time)); } mCodeTextCtrl->SetValue(mCodeText); mModifySpinCtrl->SetRange(1, mCameraTrack->getNumKeyFrames()); } }
void CameraTrackSettingDialog::OnSaveTrack(wxCommandEvent& event) { assert (mCameraTrack); assert (mCameraAnimState); wxFileDialog fileDialog(this, _("Save track file"), "", "", "Track files (*.track)|*.track", wxSAVE | wxOVERWRITE_PROMPT); if (fileDialog.ShowModal() != wxID_OK) return; wxString fullFileName = fileDialog.GetPath(); std::ofstream stream(fullFileName.c_str()); Ogre::String trackStr; trackStr += Ogre::StringConverter::toString( mCameraAnimState->getLength() ) + "," + Ogre::StringConverter::toString( mCameraTrack->getNumKeyFrames() ) + ","; for (unsigned short index = 0; index < mCameraTrack->getNumKeyFrames(); ++index) { Ogre::TransformKeyFrame* keyFrame = static_cast<Ogre::TransformKeyFrame*>( mCameraTrack->getKeyFrame(index) ); const Ogre::Vector3& pos = keyFrame->getTranslate(); const Ogre::Quaternion& ori = keyFrame->getRotation(); float time = keyFrame->getTime(); trackStr += Ogre::StringConverter::toString(pos) + "," + Ogre::StringConverter::toString(ori) + "," + Ogre::StringConverter::toString(time) + ","; } stream << trackStr.c_str(); stream.close(); }
void CameraTrackSettingDialog::OnAddPoint(wxCommandEvent& event) { const Ogre::Vector3& pos = mCamera->getPosition(); const Ogre::Quaternion& ori = mCamera->getOrientation(); float animLength = Ogre::StringConverter::parseReal( mAnimLengthTextCtrl->GetValue().c_str() ); float pointTime = Ogre::StringConverter::parseReal( mPointTimeTextCtrl->GetValue().c_str() ); if (animLength == 0.0f || pointTime > animLength) { wxMessageBox(_("the time is wrong")); return; } if (!mCameraNode) { mCameraNode = mSceneManipulator->getBaseSceneNode()->createChildSceneNode(); } if (mTrackClear) { mCameraAnimation = mSceneManipulator->getSceneManager()->createAnimation("CameraTrack", animLength); // Spline it for nice curves mCameraAnimation->setInterpolationMode(Ogre::Animation::IM_SPLINE); // Create a track to animate the camera's node mCameraTrack = mCameraAnimation->createNodeTrack(0, mCameraNode); mCameraAnimState = mSceneManipulator->getSceneManager()->createAnimationState("CameraTrack"); mTrackClear = false; } Ogre::TransformKeyFrame* key = mCameraTrack->createNodeKeyFrame(pointTime); // startposition key->setTranslate(pos); key->setRotation(ori); RefreshCodeText(); }
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); }
void CameraTrackSettingDialog::OnModifyPoint(wxCommandEvent& event) { if (mCameraTrack) { int index = mModifySpinCtrl->GetValue() - 1; if (index < mCameraTrack->getNumKeyFrames()) { Ogre::TransformKeyFrame* keyFrame = static_cast<Ogre::TransformKeyFrame*>( mCameraTrack->getKeyFrame(index) ); const Ogre::Vector3& pos = mCamera->getPosition(); const Ogre::Quaternion& ori = mCamera->getOrientation(); keyFrame->setTranslate(pos); keyFrame->setRotation(ori); RefreshCodeText(); } else { wxMessageBox(_("the index is wrong!")); } } }
void CameraTrackSettingDialog::OnLoadTrack(wxCommandEvent& event) { wxFileDialog fileDialog(this, _("Load track file"), "", "", "Track files (*.track)|*.track", wxOPEN | wxFILE_MUST_EXIST); if (fileDialog.ShowModal() != wxID_OK) return; // 先清除当前的轨迹 ClearTrack(); std::ifstream stream; stream.open( fileDialog.GetPath().c_str() ); if (stream) { Ogre::DataStreamPtr ifStream( new Ogre::FileStreamDataStream(&stream, false) ); Ogre::String line; line = ifStream->getAsString(); Ogre::StringVector paras = Ogre::StringUtil::split(line, ","); if (paras.size() >= 2) { float length = Ogre::StringConverter::parseReal(paras[0]); if (!mCameraNode) { mCameraNode = mSceneManipulator->getBaseSceneNode()->createChildSceneNode(); } if (mTrackClear) { mCameraAnimation = mSceneManipulator->getSceneManager()->createAnimation("CameraTrack", length); // Spline it for nice curves mCameraAnimation->setInterpolationMode(Ogre::Animation::IM_SPLINE); // Create a track to animate the camera's node mCameraTrack = mCameraAnimation->createNodeTrack(0, mCameraNode); mCameraAnimState = mSceneManipulator->getSceneManager()->createAnimationState("CameraTrack"); mTrackClear = false; } unsigned int keyCount = Ogre::StringConverter::parseUnsignedInt(paras[1]); for (unsigned int i=0; i<keyCount; ++i) { Ogre::Vector3 pos = Ogre::StringConverter::parseVector3(paras[2 + i*3]); Ogre::Quaternion ori = Ogre::StringConverter::parseQuaternion(paras[3 + i*3]); float time = Ogre::StringConverter::parseReal(paras[4 + i*3]); Ogre::TransformKeyFrame* key = mCameraTrack->createNodeKeyFrame(time); // startposition key->setTranslate(pos); key->setRotation(ori); } RefreshCodeText(); } } }
void WheelAnimalSceneObj::load(const std::string & filename) { //Ogre::ru * s = Orz::OgreGraphicsManager::getSingleton().getSceneManager()->getRootSceneNode()->createChildSceneNode(Ogre::Vector3(0, 0 ,0)); //导入场景资源 _impl = BaseSceneImpl::create(_osm, filename); //创建总场景节点 _senceNode = Orz::OgreGraphicsManager::getSingleton().getSceneManager()->getRootSceneNode()->createChildSceneNode(); //创建场景 _osm->createScene(_senceNode); _senceNode->setVisible(true); //s->setVisible(false); /*_impl->getCamera(SCENE_CAMERA)->setPosition(Ogre::Vector3(-98.851, 164.283, 237.886)); _impl->getCamera(SCENE_CAMERA)->setOrientation(Ogre::Quaternion(0.999578, -0.0192806, -0.0226839));*/ //创建摄像机的节点 _cameraSn = OgreGraphicsManager::getSingleton().getSceneManager()->getRootSceneNode()->createChildSceneNode(); //获取场景的摄像机 Ogre::Camera * camera = _impl->getCamera(SCENE_CAMERA); //创建摄像机的节点并设置它的位置 _cameraSn = camera->getParentSceneNode()->createChildSceneNode(Ogre::Vector3(0.f, 164.283f, 237.886f)); //_cameraSn->setPosition(Ogre::Vector3(-98.851, 164.283, 237.886)); //_cameraSn->setOrientation(Ogre::Quaternion(0.999578, -0.0192806, -0.0226839)); //camera->detatchFromParent(); //脱离原有的节点 camera->detachFromParent(); //摄像机绑定在节点上 _cameraSn->attachObject(_impl->getCamera(SCENE_CAMERA)); //创建场景的中心节点 Ogre::SceneNode * sn = getBaseCenter()->createChildSceneNode(Ogre::Vector3(0, 100,0)); //setAutoTracking可以让你的摄像机总是盯着你场景中的某一个节点 //方法中第一个参数确定是否打开自动跟踪,在任何一帧渲染之前都可以重新设置它。 //二个参数是被跟踪节点得指针,除非你第一个参数是false(这时候可以用NULL),否则你必须确定调用的时候指针指向的节点必须有效 camera->setAutoTracking(true, sn); // std::cout<<_camera->getPosition()<<"!"<<_camera->getOrientation()<<std::endl; //获取场景管理器 Ogre::SceneManager * sm = Orz::OgreGraphicsManager::getSingleton().getSceneManager(); // set up spline animation of node //定义动画,指定动画的名称及长度(这里为4秒) _anim = sm->createAnimation("Cam_", 4); //// Spline it for nice curves // // 指定动画关键帧之间的插值方式(包括线性插值和样条插值) _anim->setInterpolationMode(Ogre::Animation::IM_LINEAR); //定义动画的一个动画轨迹,并指定这个轨迹是作用到_cameraSn节点上的 //// Create a track to animate the camera's node Ogre::NodeAnimationTrack * track = _anim->createNodeTrack(0, _cameraSn); // 定义动画轨迹包含的关键帧,下面定义了3个关键帧,加上起始帧 // 4个关健帧形成了一个曲线的动画 Ogre::TransformKeyFrame* key = track->createNodeKeyFrame(0); // startposition key->setTranslate(Ogre::Vector3(0.f, 0.3f, 237.886f)); key = track->createNodeKeyFrame(3); // startposition key->setTranslate(Ogre::Vector3(0.f, 0.3f, 237.886f)); key = track->createNodeKeyFrame(4); key->setTranslate(Ogre::Vector3(0.f, -80.f, -400.f)); ////////////////////////////////// //定义动画的一个动画轨迹,并指定这个轨迹是作用到创建场景的中心节点sn上的 track = _anim->createNodeTrack(1, sn); key = track->createNodeKeyFrame(0); // startposition key->setTranslate(Ogre::Vector3(0, 0,0)); key = track->createNodeKeyFrame(3); // startposition key->setTranslate(Ogre::Vector3(0, 0,0)); key = track->createNodeKeyFrame(4); key->setTranslate(Ogre::Vector3(0, 200,0)); //// Create a new animation state to track this //定义AnimationState类的对象,它和刚才定义的动画类相对应。设置动画的状态为启用: _animState = sm->createAnimationState("Cam_"); _animState->setEnabled(true);// 启用该动画 _animState->setLoop(false); /* Ogre::MaterialPtr material = Ogre::MaterialPtr(Ogre::MaterialManager::getSingleton().getByName("Material_#11/lanseshuijing")); material->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName("shuijing-lv.dds");*/ }
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 SkeletonSerializerEx::readAnimationTrack( Ogre::DataStreamPtr& stream, Ogre::Animation* anim, Ogre::Skeleton* pSkel) { // unsigned short boneIndex : Index of bone to apply to unsigned short boneHandle; readShorts(stream, &boneHandle, 1); // Find bone Ogre::Bone *targetBone = pSkel->getBone(boneHandle); // Create track Ogre::NodeAnimationTrack* pTrack = anim->createNodeTrack(boneHandle, targetBone); // Keep looking for nested keyframes if (!stream->eof()) { unsigned short streamID = readChunk(stream); while((streamID == Ogre::SKELETON_ANIMATION_TRACK_KEYFRAME || streamID == 0x4120 ) && !stream->eof()) { if (streamID == 0x4120) { unsigned short len; unsigned short flags; readShorts(stream, &len, 1); readShorts(stream, &flags, 1); float time; for (int i = 0; i < len; i += 1) { readFloats(stream, &time, 1); Ogre::TransformKeyFrame *kf = pTrack->createNodeKeyFrame(time); Ogre::Quaternion rot = Ogre::Quaternion::IDENTITY; if (flags & 1) { readObject(stream, rot); } kf->setRotation(rot); Ogre::Vector3 trans = Ogre::Vector3::ZERO; if (flags & 2) { readObject(stream, trans); } kf->setTranslate(trans); // 为正确解析天龙八部模型的骨骼动画 Ogre::Vector3 scale = Ogre::Vector3::UNIT_SCALE; if (flags & 4) { readObject(stream, scale); } kf->setScale(scale); } } else readKeyFrame(stream, pTrack, pSkel); if (!stream->eof()) { // Get next stream streamID = readChunk(stream); } } if (!stream->eof()) { // Backpedal back to start of this stream if we've found a non-keyframe stream->skip(-STREAM_OVERHEAD_SIZE); } } }
/* 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; }