|
我是新手,请大家指点!谢谢!
程序的基本思路和现在的问题是:
用MFC+OSG实现一个动画。在MFC中有个ONTIMER事件实时刷新一些全局变量。然后希望在OSG中能根据这些全局的值实时更新动画。
现在碰到的问题是:
ONTIMER事件中,这些全局变量的数据实时刷新了。
但是OSG中只是第一次初始化后时,把这些全局变量的当前数据读进来,循环进行动画。后面没有按这些全局变量的实时值进行更新。更新回调没起作用。
请各位大侠,ARRAY老师指导!该如何修改。
源码: OSG.CPP ..............................................
double YawAngle[3];
double PitchAngle1[3];
double PitchAngle2[3];
double PitchAngle3[3];
double RotateAngle[3];
double f = 1.0; //给定数据的赫兹
void createEuler0Keyframes(osgAnimation:uatKeyframeContainer* kc) // yaw
{ //给定数据
for(int i=0;i<3;i++)
{ kc->push_back(osgAnimation::QuatKeyframe((float)(i*f),osg::Quat(osg:egreesToRadians(YawAngle[i]),osg::Vec3d(0.,0.,1.)))); }
}
void createEuler1Keyframes(osgAnimation::QuatKeyframeContainer* kc) //Rotating
{
//给定数据
for (int i=0;i<3;i++)
{ kc->push_back(osgAnimation::QuatKeyframe((float)(i*f),osg::Quat(osg::DegreesToRadians(RotateAngle[i]),osg::Vec3d(0.,1.,0.)))); }
}
void createEuler2Keyframes(osgAnimation::QuatKeyframeContainer* kc) //PitchAngle1 - Red
{
//给定数据
for(int i=0;i<3;i++)
{ kc->push_back(osgAnimation::QuatKeyframe((float)(i*f),osg::Quat(osg::DegreesToRadians(PitchAngle1[i]),osg::Vec3d(0.,0.,1.)))); }
}
void createEuler3Keyframes(osgAnimation::QuatKeyframeContainer* kc) //PitchAngle2 - Green
{
//给定数据
for(int i=0;i<3;i++)
{ kc->push_back(osgAnimation::QuatKeyframe((float)(i*f),osg::Quat(osg::DegreesToRadians(PitchAngle2[i]),osg::Vec3d(0.866,0.,-0.5)))); }
}
void createEuler4Keyframes(osgAnimation::QuatKeyframeContainer* kc) //PitchAngle3 - Blue
{
//给定数据
for(int i=0;i<3;i++)
{ kc->push_back(osgAnimation::QuatKeyframe((float)(i*f),osg::Quat(osg::DegreesToRadians(PitchAngle3[i]),osg::Vec3d(-0.866,0.,-0.5)))); }
}
void createPosition0Keyframes(osgAnimation::Vec3KeyframeContainer* kc)
{
//给定数据
float position[8]={-487.,-487.,-487.,-487.,-487.,-487.,-487.,-487.};
for(int i=0;i<=7;i++)
{ kc->push_back(osgAnimation::Vec3Keyframe((float)(i/f),osg::Vec3(0.,position[i],0.))); }
}
void createPosition1Keyframes(osgAnimation::Vec3KeyframeContainer* kc)
{
//给定数据
float position[8]={-487.,-487.,-487.,-487.,-487.,-487.,-487.,-487.};
for(int i=0;i<=7;i++)
{ kc->push_back(osgAnimation::Vec3Keyframe((float)(i/f),osg::Vec3(0.,position[i],0.))); }
}
void createPosition2Keyframes(osgAnimation::Vec3KeyframeContainer* kc)
{
//给定数据
float position[8]={-487.,-487.,-487.,-487.,-487.,-487.,-487.,-487.};
for(int i=0;i<=7;i++)
{ kc->push_back(osgAnimation::Vec3Keyframe((float)(i/f),osg::Vec3(0.,position[i],0.))); }
}
cOSG::cOSG(HWND hWnd) :
m_hWnd(hWnd), mDone(false)
{ }
cOSG::~cOSG()
{}
void cOSG::InitOSG(std::string modelname)
{
//存储加载模型的文件名
m_ModelName = modelname;
// 初始化osg
InitManipulators();
InitSceneGraph();
InitCameraConfig();
}
void cOSG::InitManipulators(void)
{
// 创建一个追踪求操作器
trackball = new osgGA::TrackballManipulator();
//创建一个调度操作器
keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
// 添加追踪球操作器到调度操作器中
keyswitchManipulator->addMatrixManipulator( '1', "Trackball", trackball.get());
// Init the switcher to the first manipulator (in this case the only manipulator)
keyswitchManipulator->selectMatrixManipulator(0); // Zero based index Value
}
void cOSG::InitSceneGraph(void)
{
// 定义主节点
mRoot = new osg::Group;
// 加载模型
mModel = osgDB::readNodeFile(m_ModelName);
fan120 = osgDB::readNodeFile("fan120.osg");
fan240 = osgDB::readNodeFile("fan240.osg");
exis = osgDB::readNodeFile("exis.osg");
engineroom = osgDB::readNodeFile("engineroom.osg");
tower = osgDB::readNodeFile("tower.osg");
//优化模型
osgUtil::Optimizer optimizer;
optimizer.optimize(mModel.get());
optimizer.optimize(fan120.get());
optimizer.optimize(fan240.get());
optimizer.optimize(exis.get());
optimizer.optimize(engineroom.get());
optimizer.optimize(tower.get());
optimizer.reset();
//添加模型到场景中
mRoot->addChild(mModel.get());
}
void cOSG::InitCameraConfig(void)
{
// Local Variable to hold window size data
RECT rect;
// 创建一个视图
mViewer = new osgViewer::Viewer();
// Add a Stats Handler to the viewer
mViewer->addEventHandler(new osgViewer::StatsHandler);
// Get the current window size
::GetWindowRect(m_hWnd, &rect);
// Init the GraphicsContext Traits
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
// Init the Windata Variable that holds the handle for the Window to display OSG in.
osg::ref_ptr<osg::Referenced> windata = new osgViewer::GraphicsWindowWin32::WindowData(m_hWnd);
// Setup the traits parameters
traits->x = 0;
traits->y = 0;
traits->width = rect.right - rect.left;
traits->height = rect.bottom - rect.top;
traits->windowDecoration = false;
traits->doubleBuffer = true;
traits->sharedContext = 0;
traits->setInheritedWindowPixelFormat = true;
traits->inheritedWindowData = windata;
// Create the Graphics Context
osg::GraphicsContext* gc = osg::GraphicsContext::createGraphicsContext(traits.get());
// Init a new Camera (Master for this View)
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
// Assign Graphics Context to the Camera
camera->setGraphicsContext(gc);
// Set the viewport for the Camera
camera->setViewport(new osg::Viewport(traits->x, traits->y, traits->width, traits->height));
// camera->setViewport(new osg::Viewport(8, 61, 251, 338));
// Add the Camera to the Viewer
mViewer->addSlave(camera.get());
// Add the Camera Manipulator to the Viewer
mViewer->setCameraManipulator(keyswitchManipulator.get());
osg::ref_ptr<osgAnimation::Skeleton> skelroot=new osgAnimation::Skeleton;
skelroot->setDataVariance(osg::Object::DYNAMIC);
skelroot->setDefaultUpdateCallback();
osg::ref_ptr<osgAnimation::Bone> bone0=new osgAnimation::Bone;
{
bone0->setDataVariance(osg::Object::DYNAMIC);
bone0->setName("bone0");
bone0->addChild(engineroom);
bone0->setDefaultUpdateCallback();
}
osg::ref_ptr<osgAnimation::Bone> bone1=new osgAnimation::Bone;
{
bone1->setDataVariance(osg::Object::DYNAMIC);
bone1->setName("bone1");
bone1->addChild(exis);
bone1->setDefaultUpdateCallback();
}
osg::ref_ptr<osgAnimation::Bone> bone2=new osgAnimation::Bone;
{
bone2->setDataVariance(osg::Object::DYNAMIC);
bone2->setName("bone2");
bone2->addChild(mRoot);
bone2->setDefaultUpdateCallback();
}
osg::ref_ptr<osgAnimation::Bone> bone3=new osgAnimation::Bone;
{
bone3->setDataVariance(osg::Object::DYNAMIC);
bone3->setName("bone3");
bone3->addChild(fan120);
bone3->setDefaultUpdateCallback();
}
osg::ref_ptr<osgAnimation::Bone> bone4=new osgAnimation::Bone;
{
bone4->setDataVariance(osg::Object::DYNAMIC);
bone4->setName("bone4");
bone4->addChild(fan240);
bone4->setDefaultUpdateCallback();
}
skelroot->addChild(bone0);
bone0->addChild(bone1);
bone1->addChild(bone2);
bone1->addChild(bone3);
bone1->addChild(bone4);
/////////////////////////////
osg::ref_ptr<osg::Group> scene = new osg::Group();
osg::ref_ptr<osgAnimation::BasicAnimationManager> mnt=new osgAnimation::BasicAnimationManager;
scene->setUpdateCallback(mnt);
scene->addChild(skelroot);
scene->addChild(tower);
osg::ref_ptr<osgAnimation::Animation> anim=new osgAnimation::Animation;
{
//anim->setStartTime(2.0);
anim->setDataVariance(osg::Object::DYNAMIC);
osg::ref_ptr<osgAnimation::QuatSphericalLinearChannel> ch0=new osgAnimation::QuatSphericalLinearChannel;
ch0->setName("quaternion");
ch0->setTargetName("bone0");
createEuler0Keyframes(ch0->getOrCreateSampler()->getOrCreateKeyframeContainer());
osg::ref_ptr<osgAnimation::QuatSphericalLinearChannel> ch1=new osgAnimation::QuatSphericalLinearChannel;
ch1->setName("quaternion");
ch1->setTargetName("bone1");
createEuler1Keyframes(ch1->getOrCreateSampler()->getOrCreateKeyframeContainer());
osg::ref_ptr<osgAnimation::QuatSphericalLinearChannel> ch2=new osgAnimation::QuatSphericalLinearChannel;
ch2->setName("quaternion");
ch2->setTargetName("bone2");
createEuler2Keyframes(ch2->getOrCreateSampler()->getOrCreateKeyframeContainer());
osg::ref_ptr<osgAnimation::Vec3LinearChannel> ch5=new osgAnimation::Vec3LinearChannel;
ch5->setName("position");
ch5->setTargetName("bone2");
createPosition0Keyframes(ch5->getOrCreateSampler()->getOrCreateKeyframeContainer());
osg::ref_ptr<osgAnimation::QuatSphericalLinearChannel> ch3=new osgAnimation::QuatSphericalLinearChannel;
ch3->setName("quaternion");
ch3->setTargetName("bone3");
createEuler3Keyframes(ch3->getOrCreateSampler()->getOrCreateKeyframeContainer());
osg::ref_ptr<osgAnimation::Vec3LinearChannel> ch6=new osgAnimation::Vec3LinearChannel;
ch6->setName("position");
ch6->setTargetName("bone3");
createPosition1Keyframes(ch6->getOrCreateSampler()->getOrCreateKeyframeContainer());
osg::ref_ptr<osgAnimation::QuatSphericalLinearChannel> ch4=new osgAnimation::QuatSphericalLinearChannel;
ch4->setName("quaternion");
ch4->setTargetName("bone4");
createEuler4Keyframes(ch4->getOrCreateSampler()->getOrCreateKeyframeContainer());
osg::ref_ptr<osgAnimation::Vec3LinearChannel> ch7=new osgAnimation::Vec3LinearChannel;
ch7->setName("position");
ch7->setTargetName("bone4");
createPosition0Keyframes(ch7->getOrCreateSampler()->getOrCreateKeyframeContainer());
anim->addChannel(ch0);
anim->addChannel(ch1);
anim->addChannel(ch2);
anim->addChannel(ch3);
anim->addChannel(ch4);
anim->addChannel(ch5);
anim->addChannel(ch6);
anim->addChannel(ch7);
}
mnt->registerAnimation(anim);
//mnt->buildTargetReference();
mnt->playAnimation(anim);
/////////////
//osgUtil::Optimizer optimizer ;
//optimizer.optimize(scene);
mViewer->setSceneData(scene);
mViewer->realize();
//mViewer->run();
/*while (!mViewer->done())
{
mViewer->frame();
} */
}
void cOSG:reFrameUpdate()
{
// Due any preframe updates in this routine
}
void cOSG::PostFrameUpdate()
{
// Due any postframe updates in this routine
}
void cOSG::Render(void* ptr)
{
cOSG* osg = (cOSG*)ptr;
osgViewer::Viewer* viewer = osg->getViewer();
viewer->run();
AfxMessageBox((LPCTSTR)"Exit Rendering Thread");
_endthread();
}
源码:COsgMFCSDIView.CPP.................................................
extern double YawAngle[3];
extern double PitchAngle1[3];
extern double PitchAngle1[3];
extern double PitchAngle2[3];
extern double PitchAngle3[3];
extern double RotateAngle[3];
void COsgMFCSDIView::OnInitialUpdate()
{
CView::OnInitialUpdate();
CString csFileName("fan0.osg");
char buf[100];
USES_CONVERSION;
strcpy(buf,csFileName);
std::string std_Name = buf;//CString 转 std::string 不支持有中文文件夹
if(std_Name.length())
{
mOSG->InitOSG(std_Name);
mThreadHandle = (HANDLE)_beginthread(&cOSG::Render, 0, mOSG);
}
SetTimer(0,1000,NULL);
}
void COsgMFCSDIView::OnTimer(UINT_PTR nIDEvent)
{
// TODO: Add your message handler code here and/or call default
YawAngle[0] = YawAngle[1];
YawAngle[1] = YawAngle[2];
YawAngle[2] = YawAngle[2] + 10.0;
if (YawAngle[2] > 180)
{YawAngle[2] = 0; }
RotateAngle[0] = RotateAngle[1];
RotateAngle[1] = RotateAngle[2];
RotateAngle[2] = RotateAngle[2] + 10.0;
if (RotateAngle[2] > 360)
{RotateAngle[2] = 0; }
PitchAngle1[0] = PitchAngle1[1];
PitchAngle1[1] = PitchAngle1[2];
PitchAngle1[2] = PitchAngle1[2] + 10.0;
if (PitchAngle1[2] > 90)
{PitchAngle1[2] = 0;}
PitchAngle2[0] = PitchAngle2[1];
PitchAngle2[1] = PitchAngle2[2];
PitchAngle2[2] = PitchAngle2[2] + 10.0;
if (PitchAngle2[2] > 90)
{PitchAngle2[2] = 0;}
PitchAngle3[0] = PitchAngle3[1];
PitchAngle3[1] = PitchAngle3[2];
PitchAngle3[2] = PitchAngle3[2] + 10.0;
if (PitchAngle3[2] > 90)
{PitchAngle3[2] = 0;}
CView::OnTimer(nIDEvent);
} |
|